10001 - Garden of Eden(dfs)

来源:互联网 发布:iphone app软件开发 编辑:程序博客网 时间:2024/05/22 00:48

题目:10001 - Garden of Eden


题目大意:题目给出元胞自动机的种类,和要处理的元胞长度,和元胞字符串,问这个元胞是否可以由其他的元胞转换而来,是的话输出REACHABLE,否则输出GARDEN OF EDEN。

这题最让人困惑的就是题意了,去搜别人的解题报告看题意结果还是看不懂,最后只能结合代码来理解题意。所以以下是我结合代码理解的题意,可能和题目原本的意思有些偏差。

这里的元胞自动机题目说最多只有256种,范围0-255,这里的元胞自动机对应的是题目中的那个表格的第四列new state,把表格上的0或1并且对应位置转换成十进制的数就代表某一类元胞自动机。(可以看下面的那个204的例子)题目的意思是问给定的字符串,是否可以由某个字符串通过指定的某个元胞自动机转换而来,这里就是要求它是否可以逆转换乘另一个字符串。然后现在就要明白转换规则:将每个字符对应自动机的规则转换成对应的新状态(有n个字符就转换n次),举个例子:

204对应的自动机:

Left Cell Right New     

[i-1]  [i]    [i + 1]  State     

0      0      0        0        0 * 20    

0       0     1        0        0 * 21   

0       1     0        1        1 * 22    

0       1     1        1        1 * 23   

1       0     0        0        0 * 24   

1       0     1        0        0 * 25   

1       1     0        1        1 * 26   

1       1     1        1        1 * 27     204(2^7 + 2^6 + 2^3 + 2^2) =Automaton Identifier 

11010(11)这个字符串转换:110 对应 1,101对应 0, 010 对应 1,101 对应 0,011对应 1;这样11010(11)<这里两个1其实是前面的两个1>.就可以通过204这个自动机转换成10101.

解题思路:

这里要逆转换的话就把看要处理的这个字符串的当前的一个字符与对应的自动机的new state的某一个是否相同,相同的话就就把对应的序列(110)存下来,然后可以发现每个新的字符要逆转换都要依靠它的前两个字符,例如110转换后就要判断是否有某个状态和0相同,且前缀为10.(除了第一个)其他的以此类推。然后到最后一个字符转换完后需要判断转换完后的后两个字符是否是下一个的前缀,这里的下一个指的是第一个,因为它是环状的。


代码:

#include <stdio.h>#include <string.h>const int N = 35;int k, n;char str[N];int news[N], solve[N], state[8];bool flag;const int dir[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 basechange () {for (int i = 0; i < 8; i++) {state[i] =  k % 2;k /= 2;}}void dfs (int cur) {if (cur == n) {if (news[0] == news[n] && news[1] == news[n + 1])flag = 1;return;}for (int i = 0; i < 8; i++)if (solve[cur] == state[i] && ( !cur || (news[cur] == dir[i][0] && news[cur + 1] == dir[i][1]))) {if (!cur) {news[0] = dir[i][0];news[1] = dir[i][1];}news[cur + 2] = dir[i][2];dfs (cur + 1);if (flag)return;}}int main () {while (scanf ("%d%d%s", &k, &n, str) != EOF) {for (int i = 0; i < n; i++ )solve[i] = str[i] - '0';basechange();flag = 0;dfs (0);if (flag)printf("REACHABLE\n");else printf("GARDEN OF EDEN\n");}return 0;}





1 0
原创粉丝点击