题目
有A、B、C三个人,每人戴一顶帽子,帽子上写有一个不为0的数,已知其中有一数为其它二数之和,每个人都可以看见其他人帽子上的数但看不到自己帽子上的数。他们都很聪明不会有失误的推理,他们所说的话均为真话并且会将当时所已经确知的事全部说出来。
A说:“我不知我帽子上的数。”
B说:“我不知我帽子上的数。”
C说:“我不知我帽子上的数。”
A说:“我不知我帽子上的数。”
B说:“我不知我帽子上的数。”
C说:“我不知我帽子上的数。”
A说:“我帽子上的数是34。”
请问:B、C帽子上的数是多少?
n和k,n表示第几次提问时有人猜出来,k表示这个人猜出来的数。例子中n=7,k=34
分析
下面,是每一个轮的每一个回合中,某方恰能猜出来的所有必要条件;
在下面的推导过程中,所有小括号()内数字比例都是 A:B:C;
中括号【】内是指该轮猜出运用的条件;
【0】: 0不是正整数(所以若看到另外两个数字相同,则自己必然是它们的和);
第 1 轮:
【1.1】A 猜出
B 和 C 相同 (2:1:1)【0】;
【1.2】B 猜出
A 和 C 相同(1:2:1) 【0】
A 是 C 的 2 倍(2:3:1)【1.1】;
(理解:B 看到 A:C=2:1,但是 A 没有猜出,所以 B 不是1,而是 3,这就是排除错误选项的方法)
【1.3】C 猜出
A 和 B 相同 (1:1:2) 【0】
A 是 B 的 2 倍 (2:1:3) 【1.1】
B 是 A 的 2 倍 (1:2:3)【1.2】
B 比 A 多 50%(2:3:5)【1.2】
第 2 轮:
(从此轮开始,每一个人的推导,都是以前两个人未猜出的表现为依据,所以每种情况的解的个数是前两个之和)
【2.1】A 猜出
(3:2:1)【1.2】
(4:3:1)【1.2】
(3:1:2)【1.3】
(4:1:3)【1.3】
(5:2:3)【1.3】
(8:3:5)【1.3】
【2.2】B 猜出
(1:3:2)【1.3】
(2:5:3)【1.3】
(1:4:3)【1.3】
(2:7:5)【1.3】
(3:4:1)【2.1】
(4:5:1)【2.1】
(3:5:2)【2.1】
(4:7:3)【2.1】
(5:8:3)【2.1】
(8:13:5)【2.1】
【2.3】 C 猜出
(3:2:5)【2.1】
(4:3:7)【2.1】
(3:1:4)【2.1】
(4:1:5)【2.1】
(5:2:7)【2.1】
(8:3:11)【2.1】
(1:3:4)【2.2】
(2:5:7)【2.2】
(1:4:5)【2.2】
(2:7:9)【2.2】
(3:4:7)【2.2】
(4:5:9)【2.2】
(3:5:8)【2.2】
(4:7:11)【2.2】
(5:8:13)【2.2】
(8:13:21)【2.2】
本题要求正整数,所以数字比例猜中的人必须是猜出数的约数;
代码
#include<iostream>
using namespace std;
int A[1000][4];//第几个解,具体解
int B[1000][4];
int C[1000][4];
int a,b,c;//解的个数
int n, k;
void f() {
if (n>3) {
for (int i = 4; i <= n; ++i) {
int l = i % 3;
if (l == 0) {
c = a + b;
for (int j = 0; j < a; ++j) {
C[j][1] = A[j][1];
C[j][2] = A[j][2];
C[j][0] = A[j][1] + A[j][2];
}
for (int j = 0; j < b; ++j) {
C[j + a][1] = B[j][1];
C[j + a][2] = B[j][2];
C[j + a][0] = B[j][1] + B[j][2];
}
}
if (l == 1) {
a = b + c;
for (int j = 0; j < b; ++j) {
A[j][0] = B[j][0];
A[j][2] = B[j][2];
A[j][1] = B[j][0] + B[j][2];
}
for (int j = 0; j < c; ++j) {
A[j+b][0] = C[j][0];
A[j+b][2] = C[j][2];
A[j+b][1] = C[j][0] + C[j][2];
}
}
if (l == 2) {
b = a + c;
for (int j = 0; j < c; ++j) {
B[j][0] = C[j][0];
B[j][1] = C[j][1];
B[j][2] = C[j][0] + C[j][1];
}
for (int j = 0; j < a; ++j) {
B[j+c][0] = A[j][0];
B[j+c][1] = A[j][1];
B[j+c][2] = A[j][0] + A[j][1];
}
}
}
}
int aa = n % 3;
if (aa == 0) {
for (int i = 0; i < c; ++i) {
if (k%C[i][0] == 0) {
int times = k / C[i][0];
cout << "[" << C[i][1] * times << "," << C[i][2] * times << "," << C[i][0] * times << "] " << endl;
}
}
}
if (aa == 1) {
//cout << "..........." << endl;
for (int i = 0; i < a; ++i) {
if (k%A[i][1] == 0) {
int times = k / A[i][1];
cout << "[" << A[i][1] * times << "," << A[i][2] * times << "," << A[i][0] * times << "] " << endl;
}
}
}
if (aa == 2) {
for (int i = 0; i < b; ++i) {
if (k%B[i][2] == 0) {
int times = k / B[i][2];
cout << "[" << B[i][1] * times << "," << B[i][2] * times << "," << B[i][0] * times << "] " << endl;
}
}
}
}
int main() {
while (1) {
cin >> n >> k;
a = 1;
A[0][1] = 2;
A[0][2] = 1;
A[0][0] = 1;
b = 2;
B[0][1] = 1;
B[0][2] = 2;
B[0][0] = 1;
B[1][1] = 2;
B[1][2] = 3;
B[1][0] = 1;
c = 4;
C[0][1] = 1;
C[0][2] = 1;
C[0][0] = 2;
C[1][1] = 2;
C[1][2] = 1;
C[1][0] = 3;
C[2][1] = 1;
C[2][2] = 2;
C[2][0] = 3;
C[3][1] = 2;
C[3][2] = 3;
C[3][0] = 5;
f();
}
return 0;
}
结果