5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果
题目
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
思路分析
问题可以转化为把排名的所有可能性都遍历一遍,即全排序,对每一种可能的排序做一次判定,如果符合题目所给条件,则打印出来,结果可能有多种,判定条件看代码注释。
过程稍有些复杂,有更好的做法,可以作为一种思路开拓来看。
代码实现
#include <iostream>
#include <algorithm>
using namespace std;
struct Person{
char ch;
int num;
};
int main()
{
Person person[][2] = {
{{'B', 2}, {'A', 3}},
{{'B', 2}, {'E', 4}},
{{'C', 1}, {'D', 2}},
{{'C', 5}, {'D', 3}},
{{'E', 4}, {'A', 1}}
};
char arr[] = {'A', 'B', 'C', 'D', 'E'};
do{
// 每个人要么是前一个回答正确,要么后一次正确,所以共32种可能
// 用二进制表示就是00000~11111的范围,0认为第一个回答正确,1选认为第二个回答正确
for(int i = 0; i < (1 << 5); i++){
bool flag = 0;
for(int j = 0; j < 5; j++){
// 如果不满足假定成立的回答或两个回答皆成立,则尝试新的方案
if((arr[person[j][(i >> j) & 1].num - 1] != person[j][(i >> j) & 1].ch) ||
(arr[person[j][0].num - 1] == person[j][0].ch &&
arr[person[j][1].num - 1] == person[j][1].ch)
){
flag = 1;
break;
}
}
if(flag) continue; // 不满足条件情况
for(int i = 0; i < 5; i++){
if(i != 0) cout << " ";
cout << arr[i];
}
cout << endl;
break; // 排序符合条件则打印
}
}while(next_permutation(arr, arr + 5));
return 0;
}
结果得到: