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
其實我的方法也不是沒有優勢,改一下問題,參考答案就掛了
問題:編程確定每個人正確的判斷並輸出
程序去掉排序輸出過程即可(這其實是最初的版本)
#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;
}