20a.c (1913B)
1 #include <inttypes.h> 2 #include <stdbool.h> 3 #include <stdio.h> 4 #include <string.h> 5 6 #define N 100 7 #define ischar(c) (c >= 'a' && c <= 'z') 8 9 typedef struct { 10 int nin, nout, in[N], out[N]; 11 char name[20], outc[N][20]; 12 bool isff, ison, reg[N]; 13 } node_t; 14 15 typedef struct { 16 int i, n, node[1000]; 17 bool hi[1000]; 18 } queue_t; 19 20 char *buf, line[N][N]; 21 int b, n; 22 int64_t hitot, lowtot; 23 node_t m[N]; 24 25 void add(queue_t *q, int v, bool hi) { 26 q->node[q->n] = v; 27 q->hi[q->n] = hi; 28 q->n++; 29 } 30 31 void send(queue_t *q, int v, bool hi) { 32 for (int j = 0; j < m[v].nout; j++) { 33 add(q, m[v].out[j], hi); 34 m[m[v].out[j]].reg[v] = hi; 35 if (hi) hitot++; else lowtot++; 36 } 37 } 38 39 void pushbutton(void) { 40 queue_t q = {0}; 41 42 add(&q, b, false); 43 lowtot++; 44 while (q.i < q.n) { 45 int v = q.node[q.i]; 46 bool hi = q.hi[q.i]; 47 q.i++; 48 49 if (v == b) { 50 send(&q, v, hi); 51 } else if (m[v].isff) { 52 if (!hi) 53 send(&q, v, m[v].ison = !m[v].ison); 54 } else { 55 bool allhi = true; 56 for (int j = 0; j < m[v].nin; j++) 57 allhi = allhi && m[v].reg[m[v].in[j]]; 58 send(&q, v, !allhi); 59 } 60 } 61 } 62 63 int main() { 64 for (n = 0; (buf = fgets(line[n], N, stdin)) != NULL; n++) { 65 if (ischar(*buf)) b = n; 66 m[n].isff = *buf == '%'; 67 if (!ischar(*buf)) buf++; 68 for (int i = 0; ischar(*buf); m[n].name[i++] = *(buf++)) ; 69 buf += 4; 70 for (int i = 0; *buf != '\n'; i++) { 71 while (!ischar(*buf)) buf++; 72 for (int j = 0; ischar(*buf); m[n].outc[i][j++] = *(buf++)) ; 73 } 74 } 75 76 for (int i = 0; i < n; i++) { 77 for (int j = 0; m[i].outc[j][0]; j++) { 78 bool found = false; 79 for (int k = 0; k < n; k++) { 80 if (!strcmp(m[k].name, m[i].outc[j])) { 81 m[i].out[m[i].nout++] = k; 82 m[k].in[m[k].nin++] = i; 83 found = true; 84 } 85 } 86 if (!found) { 87 m[i].out[m[i].nout++] = n; 88 m[n].in[m[n].nin++] = i; 89 n++; 90 } 91 } 92 } 93 94 for (int i = 0; i < 1000; i++) 95 pushbutton(); 96 97 printf("%" PRId64 "\n", hitot * lowtot); 98 return 0; 99 }