这题意思太难懂了,看了半天。
说说我理解出来的的意思:
有256种转化机制。
Left | Cell | Right | New | |||||
[i-1] | [i] | [i + 1] | State | |||||
0 | 0 | 0 | 0 | 0 * 20 | ||||
0 | 0 | 1 | 1 | 1 * 21 | ||||
0 | 1 | 0 | 0 | 0 * 22 | ||||
0 | 1 | 1 | 1 | 1 * 23 | ||||
1 | 0 | 0 | 1 | 1 * 24 | ||||
1 | 0 | 1 | 0 | 0 * 25 | ||||
1 | 1 | 0 | 1 | 1 * 26 | ||||
1 | 1 | 1 | 0 | 0 * 27 | ||||
90 | = | Automaton Identifier | ||||||
前三列就是说如果刚好碰到连续三个是前三列这样的,就把中间那个转化成第四列。。而转化的规则就是2进制,例如图中的90 ,90的二进制是01011010 就是图中第四列。。又比如204 转化为二进制就是11001100 ,发现这个数和中间那一列一样,也就是任何一串字符用204转化永远是本身。。
然后题目要求就是问给出的字符创,在这种转化机制下,能否由其他串转化来,就是要构成一环。而且是要逆向dfs(),也就是根据这个位置上的数,填上它前面的后面的。。比如90这个转化机制,如果某个字符是1 ,那么之前就可能这个字符是0,它前一个是0,后一个是1(参照图中第二行)。一直推断到最后,看看最后一个的后一个是不是等于第一个,最后一个的后两个是不是等于第二个,如果是则循环了,那就可以。
AC代码:
#include <stdio.h>
#include <string.h>
int k, n;
char aft[35];
int aftn[35];
int id[10];
int res[35];
int ok;
int d[8][3] = {{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}};
void dfs(int num) {
if (ok == 1)
return;
if (num == n) {
if (res[0] == res[num] && res[1] == res[num + 1]) {
ok = 1;
}
return;
}
for (int i = 0; i < 8; i ++) {
if (aftn[num] == id[i] && (num == 0 || res[num] == d[i][0] && res[num + 1] == d[i][1])) {
if (num == 0) {
res[num] = d[i][0];
res[num + 1] = d[i][1];
}
res[num + 2] = d[i][2];
dfs(num + 1);
}
}
}
int main() {
while (scanf("%d%d%s", &k, &n, aft) != EOF) {
ok = 0;
memset(res, 0, sizeof(res));
for (int i = 0; i < n; i ++) {
aftn[i] = aft[i] - '0';
}
for (int i = 0; i < 8; i ++) {
id[i] = k % 2;
k /= 2;
}
dfs(0);
if (ok)
printf("REACHABLE\n");
else
printf("GARDEN OF EDEN\n");
}
return 0;
}