
程序代码:
#include <stdio.h>
int main(void)
{
enum { A = 0, B, C, D, E };
int result = 0; //A的真实名次
bool isok = true; //已知条件能否锁定A的名次
int really[5]; //真实名次
int guess[5][2][2] = { {{B, 2},{A, 3}}, {{B, 2},{E, 4}}, {{C, 1},{D, 2}}, {{C, 5},{D, 3}}, {{E,4},{A,1}} }; //[guesser][guessed][results]
for (size_t _case = 1; _case <= 32; _case++) //2^5种组合
{
bool self_consistency = true; //本组猜测是否自洽
int num = 5; //本组合猜测涉及人数
for (size_t contestant = A; contestant <= E; contestant++) //实际排名置空
really[contestant] = 0;
for (size_t guesser = A; guesser <= E && self_consistency; guesser++) //将每个人猜测的其中一个赋给真实排名
if (!really[guess[guesser][_case >> guesser & 1][0]]) //排名为0,说明没有被猜过
{
for (size_t guessed = A; guessed <= E && self_consistency; guessed++)
self_consistency = really[guessed] != guess[guesser][_case >> guesser & 1][1]; //如果该名次已被其他人占用,不自洽
really[guess[guesser][_case >> guesser & 1][0]] = guess[guesser][_case >> guesser & 1][1];
}
else if (really[guess[guesser][_case >> guesser & 1][0]] != guess[guesser][_case >> guesser & 1][1]) //两个人猜一个人名次不一致,不自洽
self_consistency = false;
else
num--;
if (num == 4)
for (size_t contestant_1 = A; contestant_1 <= E; contestant_1++) //补齐排名
{
if (really[contestant_1])
continue;
really[contestant_1] = 15;
for (size_t contestant_2 = A; contestant_2 <= E; contestant_2++)
if (contestant_1 != contestant_2)
really[contestant_1] -= really[contestant_2];
}
else if (num < 4)
continue;
for (size_t contestant = A; contestant <= E; contestant++) //判断每个人是否都只猜中一半
if (really[guess[contestant][0][0]] == guess[contestant][0][1] && really[guess[contestant][1][0]] == guess[contestant][1][1])
{
self_consistency = false;
break;
}
if (!self_consistency) //不自洽,退出本次循环
continue;
if (result && (really[A] != result))
{
printf("%d %d\n", result, really[A]);
isok = false;
break;
}
else
result = really[A];
}
if (isok && result)
printf("A是第%d名\n", result);
else
printf("已知条件无法确定A的名次\n");
return 0;
}
[此贴子已经被作者于2021-1-29 17:13编辑过]