五個運動員各兩個個判斷,每人對一個,

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;
}

也可以輸出錯誤的判斷,自己開發吧。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章