只试了示例的数据,不知道其他的可不可以
#include
int main() {
int n;
while ((scanf("%d", &n)) == 1) {
int a[n][n], s[n][n], b[n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (i == j)
a[i][j] = s[i][j] = i + 1;
else
a[i][j] = s[i][j] = 0;
for (int i = 0; i < n; i++)
scanf("%d", &b[i]);
int x = 0;
while (1) {
x++;
if (x >= n) {
printf("No solution!\n");
break;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
if (a[i][j] != 0)
s[b[i] - 1][j] = a[i][j];
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
a[i][j] = s[i][j];
int k;
for (k = 0; k < n; k++)
if (a[n - 1][k] != k + 1)
break;
if (k == n && x < n) {
printf("%d\n", x);
break;
}
}
}
return 0;
}
思路也很简单。
设定一个一维数组,数组长度为n-1。因为第n个人为Taylor本人,他本人肯定知道自己的秘密。其初始值全部为0,表示还不知道秘密。
再设定一个一维数组,长度为n,用来接收传递规则。
再设一个bool变里,是否已全部找到。初始值为false
现在开始for循环,没有找到且在循环次数内,就循环。循环次数,就是需要经过多少轮。最多不会超过n轮。当然经过一些深入分析,可以减少循环轮数。这里不管了。
第二层for循环,长度就是n。循环传递规则
依次从规则数组里把传递对象取出来,
这里要判断一下传的对象是不是n,是n代表本人,到了本人了就去遍历一下秘密数组其组是否全部为1。如果全部为1,表示已全部知道秘密了,并置找到的bool变量为true,并结束本层循环。
如果不是n,则把秘密数组对应的值 设为1。
另外如何判断秘密数组全部是1?
遍历秘密数组,如果是0就break。如果是1就不管。
本for循环结束后,判断循环变量是不是大于n-1.如果是则表明for是由次数超标而结束,则是全部是1。如果不大于n-1。则表明是由于break结束的。肯定是没有全部找到。
如果循环变里从,0和从1开始循环要注意。
#include
用n*n的二维数组,i行i列赋值为i,比如第一个例子就是{{1000}{0200}{0030}{0004}},然后1告诉2就变成了{{1000}{1200}{0030}{0004}},2告诉4,{{1000}{1200}{0030}{1204}},3告诉2,{{1000}{1230}{0030}{1204}},4告诉1,{{1204}{1230}{0030}{1204}},第一轮就这样,当第四行1234齐了就break,当整个数组没变化也break,就是没有答案