逻辑推理
某小学最近举行一次田径运动会,人们对一贯刻苦锻炼的5名学生的短跑成绩作了如下的估计:A说:“第二名是D,第三名是B”,B说:“第二名是C,第四名是E”,C说:“第一名是E,第五名是A”.D说:“第三名是C,第四名是A”,E说:“第二名是B,第五名是D”。这5位同学每人说对了一半,请你猜一猜5位同学的名次。考的类似谭浩强 c的第三章课后习题最后一道乒乓球,“c实现,用简单的暴力求解“用简单的暴力算法求解,要求c++基础水平的人能写出来
巧思:
1> 学生A~E分别【数字化】为0~4,方便判断逻辑命题是否正确
2> 遍历学生排名的【全排列】,对于每一个全排列:
遍历每一个学生的讲述
————>分别求解两个命题c1,c2正确还是错误
————>c1,c2全对/全错———>当前全排列invalid————>break;
————>当valid时————>输出排名
#include <iostream>
#include <algorithm> // 用于next_permutation
using namespace std;
int main() {
// 学生编号:A=0, B=1, C=2, D=3, E=4
int students[] = {0, 1, 2, 3, 4}; // 可能不需要这个数组?
// 每个说话者的两个条件,按顺序A、B、C、D、E
struct Condition {
int pos; // 名次的位置,如0表示第一名,1表示第二名,等等
int student;
};
Condition statements[5][2] = {
{{1, 3}, {2, 1}}, // A的陈述:第二名D,第三名B
{{1, 2}, {3, 4}}, // B的陈述:第二名C,第四名E
{{0, 4}, {4, 0}}, // C的陈述:第一名E,第五名A
{{2, 2}, {3, 0}}, // D的陈述:第三名C,第四名A
{{1, 1}, {4, 3}}, // E的陈述:第二名B,第五名D
};
// 生成所有可能的排列,每个排列是一个可能的排名
int p[5] = {0, 1, 2, 3, 4}; // 初始排列是A,B,C,D,E的顺序
do {
bool valid = true;
for (int speaker = 0; speaker < 5; ++speaker) {
// 检查该说话者的两个条件是否恰好一个正确
Condition cond1 = statements[speaker][0];
Condition cond2 = statements[speaker][1];
bool c1 = (p[cond1.pos] == cond1.student);
bool c2 = (p[cond2.pos] == cond2.student);
if ((c1 && c2) || (!c1 && !c2)) { // 同时正确或同时错误,不符合条件
valid = false;
break;
}
}
if (valid) {
// 输出结果
cout << "正确名次为:";
for (int i = 0; i < 5; ++i) {
cout << char('A' + p[i]) << " ";
}
cout << endl;
return 0; // 找到解后直接退出
}
} while (next_permutation(p, p + 5));
cout << "未找到解" << endl;
return 0;
}