8b.c (1941B)
1 /* 2 I hate this stupid problem. There are a bunch of unwritten properties 3 of the paths that make the problem very simple: 4 5 - Different ghosts' paths do not end up in the same Z-node. 6 - Each ghost has exactly one Z-node in its path. 7 - Each ghost meets a Z-node exactly once before entering a loop. 8 - If a ghost encounters a Z-node after X steps, it will encounter it exactly 9 every X steps; preperiods just end up aligning nicely. 10 11 In practice, everything just works out so that the lcm of the periods 12 is the solution, which is very much not the case for a general input. 13 This code computes the periods of the paths of the different ghosts. Then 14 you can figure out the solution with a pocket calculator, or by hand. 15 */ 16 17 #include <stdio.h> 18 #include <string.h> 19 20 #define N 1000 21 22 typedef struct { char last; int next[2]; } node_t; 23 24 int v[N*N]; 25 26 int ind(char s[3], char m[][3], int n) { 27 for (int j = 0; j < n; j++) 28 if (s[0] == m[j][0] && s[1] == m[j][1] && s[2] == m[j][2]) 29 return j; 30 return -1; 31 } 32 33 int findperiod(int i, node_t *nodes, char *dir, int n, int k) { 34 memset(v, 0, sizeof(int) * N*N); 35 for (int j = i, d = 0, l = 1, state = -1; ; d = (d+1)%k) { 36 j = nodes[j].next[dir[d] == 'R']; 37 state = j*k+d; 38 if (v[state]) return l - v[state]; 39 else v[state] = l++; 40 } 41 return -1; 42 } 43 44 int main() { 45 node_t nodes[N]; 46 char *buf, dir[N], line[N], name[N][3], lstr[N][3], rstr[N][3]; 47 int k, n; 48 49 k = strlen(fgets(dir, N, stdin)) - 1; 50 fgets(line, N, stdin); 51 for (n = 0; (buf = fgets(line, N, stdin)) != NULL; n++) { 52 memcpy(name[n], buf, 3); 53 nodes[n].last = name[n][2]; 54 while (*buf != '(') buf++; 55 memcpy(lstr[n], buf+1, 3); 56 while (*buf != ' ') buf++; 57 memcpy(rstr[n], buf+1, 3); 58 } 59 60 for (int i = 0; i < n; i++) { 61 nodes[i].next[0] = ind(lstr[i], name, n); 62 nodes[i].next[1] = ind(rstr[i], name, n); 63 } 64 65 for (int i = 0; i < n; i++) 66 if (nodes[i].last == 'A') 67 printf("%d\n", findperiod(i, nodes, dir, n, k)); 68 69 return 0; 70 }