栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

C语言实现 猜排名

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言实现 猜排名

题目:

A选手说:B第二,我第三
B选手说:我第二,E第四

C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;


比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

分析:

 因为每个人说了2/5种情况,而只说对1/2
 所以每个人说的情况正确的几率是1/5
 五人说的都对的概率则为(1/5)^5=1/125
 
 所以本题采用遍历所有情况求得
 
 1.首先当然要给出所有的情况
 2.因为每个人都是一个独立的个体,所以要创建一个数组来存放五个人说的话
        设存放选手的数组为p,那么从p[0]~p[4]这五个元素则对应A B C D E五个人
 
 3.而每个元素的值则对应该该选手的排名
        例如p[3]=2,代表选手D排第2名
 
 4.我们可以通过五个循环来遍历p[0]~[4],并且对p中元素的值进行修改
 
 5.而每个人又给出了两种排名,其中只有一种是对的
        例如A选手说:B第二,我第三;
        那么p[1]==2和p[0]==3只有一个是对的
        所以要对这两种情况进行判断,如果都对或都不对就不符合条件
        书写方式为 if( (p[1]==2) + (p[0]==3) ) == 1
        因为当p[1]==2成立,返回值为1,如果此时p[0]==3也成立,相加得2,不符合条件
        通过这种方式可以对五个人说的话进行判断,如果每个人说的都只有一句是对的才进行后续操作
 
6.只判断每个人说的都只有一句是对的还不够,我们还要判断是不是有人的排名重复了,如果排名重复了也是不行的
        这里要写一个函数判断排名是否重复,而且要和五个人说的话一起进行判断,如果六个条件都成立,才能确定真正的排名
        我们可以设当排名不重复,函数返回值为1,当排名重复,函数返回值为0,这样和前面五个条件一起判断是就能通过&&来实现同时判断
            在函数内部创建一个数组tmp,这个数组用来当做排名表,该表初始化为全0,代表该名次尚未有选手占用,如果未被占用,则把该排名的值改为1 
                     例如tmp[1] = 0,代表第二名尚未被占用,tmp[3]=1,代表第四名已经被占用
            每次写入新排名的选手时都要检查一下该排名是否已经被占用,如果该排名被占用(已经有选手了),说明排错了!要重新进行排名,所有排名都要重新进行,前面所有的假设都不成立,return 0;
            当没有出现排名重复的情况,说明排对了,return 1;
 
 7.当六个条件都成立的时候,就可以对排名进行打印了

源码:

int checkData(int* p)
{
	//创建一个表,存放排名
	int tmp[7] = { 0 }; //标记表,实际是哈希表的思路。一开始每个元素都是0。
	//建立选手
	int j;
	//遍历该表
	//tmp[p[0]]代表选手A的排名,例如p[0]==1,代表A是第一名为真,则tmp[p[0]]==tmp[1]==1,即第一名已经被占了
	//tmp[p[3]]代表选手D的排名,若p[3]==2,代表D是第二名为真,则tmp[p[3]]==tmp[2]==1,即第二名已经确定了
	for (j = 0; j < 5; j++)
	{
		//判断是否出现重复的排名
		//如果某个名次的人员已经确定了,该名次的值为1
		//此时如果发现还有一个人也可能是这个排名,因为每个名次只能给一个人,不能出现并列的情况,那么说明这两个人的排名有冲突,说明排错了
		//排错了的话所有排名都要重新进行,前面所有的假设都不成立
		if (tmp[p[j]])
		{
			return 0;
		}
		//当不出现重登排名的时候,把名次给占用,值改为1
		tmp[p[j]] = 1;
	}
	return 1; //全部标记完毕也没有出现重复的情况,代表OK。
}

int main()
{
	//x-1代表这种情况是选手x说的,p[x-1]的值代表选手x的名次
	int p[5]; //0 1 2 3 4分别代表a b c d e

	//通过循环实现125种情况
	for (p[0] = 1; p[0] <= 5; p[0]++)
	{
		for (p[1] = 1; p[1] <= 5; p[1]++)
		{
			for (p[2] = 1; p[2] <= 5; p[2]++)
			{
				for (p[3] = 1; p[3] <= 5; p[3]++)
				{
					for (p[4] = 1; p[4] <= 5; p[4]++) //五层循环遍历
					{
						//这里是五个人的描述,由于比较表达式只有0和1两个结果,如果要两个条件有且只有一个为真,则可以用比较表达式的值总和为1的方式直接判定。别忘了还要判定不能并列。
							//此处判断
							//因为每个人说的两种情况只有一种是对的,所以当其中一个为真,返回值为1,当其中两个为真,返回值为2,都为假返回值为0
						if ((p[1] == 2) + (p[0] == 3) == 1 && //A选手说:B第二,我第三	
							(p[1] == 2) + (p[4] == 4) == 1 && //B选手说:我第二,E第四
							(p[2] == 1) + (p[3] == 2) == 1 && //C选手说:我第一,D第二
							(p[2] == 5) + (p[3] == 3) == 1 && //D选手说:C最后,我第三
							(p[4] == 4) + (p[0] == 1) == 1 && //E选手说:我第四,A第一
							checkData(p) //不能并列
							)
						{
							for (int i = 0; i < 5; i++)
							{
								printf("p[%d] = %d ", i, p[i]);
								putchar('n');
							}
						}
					}
				}
			}
		}
	}

	return 0;
}

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1039949.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号