五个运动员各两个个判断,每人对一个,

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果
A选手说:B第一,我第三。
B选手说:我第二,E第四。
C选手说:我第一,D第二。
D选手说:C最后,我第三。
E选手说:我第四,A第一。
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。


我的解题方法:完全将题转换成C语言,列出所有可能,判断后输出

有点长,清除格式好看点

#define _CRT_SECURE_NO_WARNINGS 

#include<stdio.h>
#include<windows.h>


int main()
{
	int i[5] = { 0 };//分别对应A~E说的某一句话
	int a[5][2][2] = { { 2, 1, 1, 3 }, { 2, 2, 5, 4 }, { 3, 1, 4, 2 }, { 3, 5, 4, 3 }, { 5, 4, 1, 1 } };
	      //第一维[5]表示A到E说的话,第二维[2]表示说的第一句和第二局话,
	      //第三维[2]表示每句话的内容,第一个数(1~5)对应(A~E),第二个数表示名次。
	for (i[0] = 0; i[0] < 2; i[0]++)
	{
		for (i[1] = 0; i[1] < 2; i[1]++)     //五个for循环列出所有可能出现的情况
		{
			for (i[2] = 0; i[2] < 2; i[2]++) //例如:i[0]=1表示第(0+1)个人说的第(0+1)句话是正确的
			{
				for (i[3] = 0; i[3] < 2; i[3]++)
				{
					for (i[4] = 0; i[4] < 2; i[4]++)
					{
						int j = 0;
						int k = 0;
						
						for (j = 0; j < 5; j++) //这个嵌套for循环用于判断所选出的判断相互不冲突
						{						
							for (k = (j + 1); k < 5; k++)//外层循环表示选出的一个判断,内层表示另一个
							{
								if ((a[j][i[j]][0] == a[k][i[k]][0]) && (a[j][i[j]][1] != a[k][i[k]][1]))
								{				//当同一个人            有不同名次
									goto bool;	//不符合条件,结束此次判断
								}
							}
						}
						for (k = 0; k < 5; k++)	//这个两层for循环用于判断未选出的语句是错误的
						{						//!i[k]表示第(k+1)个人未选出的语句
							for (j = 0; j < 5; j++)		//与五个正确语句比较
							{											   //选出的语句        错误语句
								if (((a[j][i[j]][0] == a[k][!i[k]][0]) && (a[j][i[j]][1] != a[k][!i[k]][1])) || //同一个人不同名次或
									((a[j][i[j]][0] != a[k][!i[k]][0]) && (a[j][i[j]][1] == a[k][!i[k]][1])))	//人不同名次相同
								{				
									break;		//该语句与选出语句冲突,判断下条语句
								}
							}
							if (j == 5)			//该语句不与选出的语句冲突,语句为真,有人两个判断都正确
							{
								goto bool;		//结束此次判断
							}
						}
						for (j = 1; j <= 5; j++)	//从A到E确定名次
						{
							for (k = 0; k < 5; k++)	//从正确语句中找A到E
							{
								if (a[k][i[k]][0]==j)	//找到就输出
								{
									printf("%c 是第 %d 名。\n", ('A' + j - 1), a[k][i[k]][1]);
									goto bol;	//找下一个
								}
							}
							//没找到
							for (k = 1; k <= 5; k++)	//从第一名开始找空缺的名次
							{
								if ((a[0][i[0]][1] != k)&&(a[1][i[1]][1] != k)&&
									(a[2][i[2]][1] != k)&&(a[3][i[3]][1] != k)&&
									(a[4][i[4]][1] != k))//空缺名次必同时不等于所有已有名次
								{													
									printf("%c 是第 %d 名。\n", ('A' + j - 1), k);	
									goto bol;	//找下一个
								}
							}
						bol: continue;			//找下一个人
						//printf("%c 是第 %d 名。\n", ('A' + a[j][i[j]][0]- 1) , a[j][i[j]][1]);>>之前用于直接输出正确语句
						}
						bool : continue;		//结束一次判断,开始判断下一种可能
					}
				}
			}
		}
	}
	system("pause");
	return 0;
}
 
运行结果

我知道看到这心里坑定艹了,我自己都艹了,这么长还理论上有bug

来看看参考答案

解题方法:定义A~E为变量,赋值名词次,五个for循环给出所有可能,条件判断,

                 名次从1开始的连续性判断,通过输出

看代码

#define _CRT_SECURE_NO_WARNINGS 

  
  
#include<stdio.h> #include<windows.h>
int main() {  int a = 0, b = 0, c = 0, d = 0, e = 0;  for (a = 1; a <= 5; a++)  {   for (b = 1; b <= 5; b++)   {    for (c = 1; c <= 5; c++)    {     for (d = 1; d <= 5; d++)     {      for (e = 1; e <= 5; e++)      {       int count = 0;       if (((b == 1) + (a == 3) == 1) &&        ((b == 2) + (e == 4) == 1) &&        ((c == 1) + (d == 2) == 1) &&        ((c == 5) + (d == 3) == 1) &&        ((e == 4) + (a == 1) == 1))       {        count |= 1 << (a - 1);        count |= 1 << (b - 1);        count |= 1 << (c - 1);        count |= 1 << (d - 1);        count |= 1 << (e - 1);        while (count % 2 != 0)        {         count /= 2;        }        if (count == 0)        {         printf("A是第%d名\nB是第%d名\nC是第%d名\nD是第%d名\nE是第%d名\n", a, b, c, d, e);        }       }      }     }    }   }  }  system("pause");  return 0; }
 

其实我的方法也不是没有优势,改一下问题,参考答案就挂了

问题:编程确定每个人正确的判断并输出

程序去掉排序输出过程即可(这其实是最初的版本)

#define _CRT_SECURE_NO_WARNINGS 

#include<stdio.h>
#include<windows.h>

int main()
{
	int i[5] = { 0 };//分别对应A~E说的某一句话
	int a[5][2][2] = { { 2, 1, 1, 3 }, { 2, 2, 5, 4 }, { 3, 1, 4, 2 }, { 3, 5, 4, 3 }, { 5, 4, 1, 1 } };
	//第一维[5]表示A到E说的话,第二维[2]表示说的第一句和第二局话,
	//第三维[2]表示每句话的内容,第一个数(1~5)对应(A~E),第二个数表示名次。
	for (i[0] = 0; i[0] < 2; i[0]++)
	{
		for (i[1] = 0; i[1] < 2; i[1]++)     //五个for循环列出所有可能出现的情况
		{
			for (i[2] = 0; i[2] < 2; i[2]++) //例如:i[0]=1表示第(0+1)个人说的第(0+1)句话是正确的
			{
				for (i[3] = 0; i[3] < 2; i[3]++)
				{
					for (i[4] = 0; i[4] < 2; i[4]++)
					{
						int j = 0;
						int k = 0;

						for (j = 0; j < 5; j++) //这个嵌套for循环用于判断所选出的判断相互不冲突
						{
							for (k = (j + 1); k < 5; k++)//外层循环表示选出的一个判断,内层表示另一个
							{
								if ((a[j][i[j]][0] == a[k][i[k]][0]) && (a[j][i[j]][1] != a[k][i[k]][1]))
								{				//当同一个人            有不同名次
									goto bool;	//不符合条件,结束此次判断
								}
							}
						}
						for (k = 0; k < 5; k++)	//这个两层for循环用于判断未选出的语句是错误的
						{						//!i[k]表示第(k+1)个人未选出的语句
							for (j = 0; j < 5; j++)		//与五个正确语句比较
							{											   //选出的语句        错误语句
								if (((a[j][i[j]][0] == a[k][!i[k]][0]) && (a[j][i[j]][1] != a[k][!i[k]][1])) || //同一个人不同名次或
									((a[j][i[j]][0] != a[k][!i[k]][0]) && (a[j][i[j]][1] == a[k][!i[k]][1])))	//人不同名次相同
								{
									break;		//该语句与选出语句冲突,判断下条语句
								}
							}
							if (j == 5)			//该语句不与选出的语句冲突,语句为真,有人两个判断都正确
							{
								goto bool;		//结束此次判断
							}
						}
						for (j = 0; j < 5; j++)
						{
							printf("%c判断%c 是第 %d 名正确。\n", ('A' + j), ('A' + a[j][i[j]][0] - 1), a[j][i[j]][1]);
						}
						bool : continue;		//结束一次判断,开始判断下一种可能
					}
				}
			}
		}
	}
	system("pause");
	return 0;
}

也可以输出错误的判断,自己开发吧。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值