#include <stdio.h> #define min(a, b) ((a) < (b) ? (a) : (b)) #define MAX_N 100000 #define INF 1000000000 struct state { int a, b, c; int t; }; struct state conf; struct state queue[3*MAX_N+1]; int answer[MAX_N+1]; bool taken_al[MAX_N+1]; bool taken_ah[MAX_N+1]; bool taken_bl[MAX_N+1]; bool taken_bh[MAX_N+1]; bool taken_cl[MAX_N+1]; bool taken_ch[MAX_N+1]; void make(struct state *s, int a, int b, int c) { s->a = a; s->b = b; s->c = c; } void mark(struct state *s) { answer[s->a] = min(answer[s->a], s->t); answer[s->b] = min(answer[s->b], s->t); answer[s->c] = min(answer[s->c], s->t); } bool insert(struct state *s) { bool *target; bool res; if (s->a == 0) target = &taken_al[s->b]; else if (s->a == conf.a) target = &taken_ah[s->b]; else if (s->b == 0) target = &taken_bl[s->c]; else if (s->b == conf.b) target = &taken_bh[s->c]; else if (s->c == 0) target = &taken_cl[s->a]; else if (s->c == conf.c) target = &taken_ch[s->a]; else return true; res = *target; *target = true; return res; } int main(void) { struct state init; struct state next; struct state *head, *tail; int m; int i; scanf("%d%d%d", &conf.a, &conf.b, &conf.c); scanf("%d%d%d", &init.a, &init.b, &init.c); for (i = 0; i <= conf.c; i++) answer[i] = INF; queue[0] = init; head = &queue[0]; tail = &queue[1]; for (; head < tail; head++) { mark(head); next.t = head->t + 1; /* a -> b */ m = min(head->a, conf.b - head->b); make(&next, head->a - m, head->b + m, head->c); if (!insert(&next)) *tail++ = next; /* b -> c */ m = min(head->b, conf.c - head->c); make(&next, head->a, head->b - m, head->c + m); if (!insert(&next)) *tail++ = next; /* c -> a */ m = min(head->c, conf.a - head->a); make(&next, head->a + m, head->b, head->c - m); if (!insert(&next)) *tail++ = next; /* b -> a */ m = min(head->b, conf.a - head->a); make(&next, head->a + m, head->b - m, head->c); if (!insert(&next)) *tail++ = next; /* c -> b */ m = min(head->c, conf.b - head->b); make(&next, head->a, head->b + m, head->c - m); if (!insert(&next)) *tail++ = next; /* a -> c */ m = min(head->a, conf.c - head->c); make(&next, head->a - m, head->b, head->c + m); if (!insert(&next)) *tail++ = next; } for (i = 0; i <= conf.c; i++) printf("%d ", answer[i] < INF ? answer[i] : -1); printf("\n"); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | #include <stdio.h> #define min(a, b) ((a) < (b) ? (a) : (b)) #define MAX_N 100000 #define INF 1000000000 struct state { int a, b, c; int t; }; struct state conf; struct state queue[3*MAX_N+1]; int answer[MAX_N+1]; bool taken_al[MAX_N+1]; bool taken_ah[MAX_N+1]; bool taken_bl[MAX_N+1]; bool taken_bh[MAX_N+1]; bool taken_cl[MAX_N+1]; bool taken_ch[MAX_N+1]; void make(struct state *s, int a, int b, int c) { s->a = a; s->b = b; s->c = c; } void mark(struct state *s) { answer[s->a] = min(answer[s->a], s->t); answer[s->b] = min(answer[s->b], s->t); answer[s->c] = min(answer[s->c], s->t); } bool insert(struct state *s) { bool *target; bool res; if (s->a == 0) target = &taken_al[s->b]; else if (s->a == conf.a) target = &taken_ah[s->b]; else if (s->b == 0) target = &taken_bl[s->c]; else if (s->b == conf.b) target = &taken_bh[s->c]; else if (s->c == 0) target = &taken_cl[s->a]; else if (s->c == conf.c) target = &taken_ch[s->a]; else return true; res = *target; *target = true; return res; } int main(void) { struct state init; struct state next; struct state *head, *tail; int m; int i; scanf("%d%d%d", &conf.a, &conf.b, &conf.c); scanf("%d%d%d", &init.a, &init.b, &init.c); for (i = 0; i <= conf.c; i++) answer[i] = INF; queue[0] = init; head = &queue[0]; tail = &queue[1]; for (; head < tail; head++) { mark(head); next.t = head->t + 1; /* a -> b */ m = min(head->a, conf.b - head->b); make(&next, head->a - m, head->b + m, head->c); if (!insert(&next)) *tail++ = next; /* b -> c */ m = min(head->b, conf.c - head->c); make(&next, head->a, head->b - m, head->c + m); if (!insert(&next)) *tail++ = next; /* c -> a */ m = min(head->c, conf.a - head->a); make(&next, head->a + m, head->b, head->c - m); if (!insert(&next)) *tail++ = next; /* b -> a */ m = min(head->b, conf.a - head->a); make(&next, head->a + m, head->b - m, head->c); if (!insert(&next)) *tail++ = next; /* c -> b */ m = min(head->c, conf.b - head->b); make(&next, head->a, head->b + m, head->c - m); if (!insert(&next)) *tail++ = next; /* a -> c */ m = min(head->a, conf.c - head->c); make(&next, head->a - m, head->b, head->c + m); if (!insert(&next)) *tail++ = next; } for (i = 0; i <= conf.c; i++) printf("%d ", answer[i] < INF ? answer[i] : -1); printf("\n"); return 0; } |