AOJ 0503: Cup [AOJ]
JOI予選の問題、全ての年で問4まで解けました.ばんざーい!
Greedyとか漸化式とか言う話がチラチラ聞こえましたが、僕にある武器はDFSとBFSだけだったのです...
訪問状態の管理は3進数で行なっています. 3^15 ≒15000000です.
Greedyとか漸化式とか言う話がチラチラ聞こえましたが、僕にある武器はDFSとBFSだけだったのです...
訪問状態の管理は3進数で行なっています. 3^15 ≒15000000です.
#include <stdio.h> #include <string.h> typedef struct { int time; int tower[3][15]; int t[3]; } HANOI; HANOI queue[50000]; int head, tail; int pow[30]; void enq(HANOI t) { queue[tail % 50000] = t; tail++; } void deq(HANOI *t) { *t = queue[head % 50000]; head++; } char v[15000000]; int move(HANOI temp, int from, int to, int pw) { int num; int i, j; HANOI first; if ((temp.t[from] > 0 && temp.t[to] > 0 && temp.tower[from][temp.t[from] - 1] > temp.tower[to][temp.t[to] - 1]) ||temp.t[from] > 0 && temp.t[to] == 0){ first = temp; first.tower[to][temp.t[to]] = first.tower[from][temp.t[from] - 1]; first.tower[from][temp.t[from] - 1] = 0; first.t[from]--; first.t[to]++; first.time++; num = 0; for (i = 0; i < 3; i++){ for (j = 0; j < first.t[i]; j++){ num += i * pow[first.tower[i][j] - 1]; } } if (v[0] == 1 || v[pw] == 1){ printf("%d\n", first.time); return (1); } if (!v[num]){ v[num] = 1; enq(first); } } return (0); } int main(void) { int n, m; HANOI start, temp; int i, j; int pw; pow[0] = 1; for (i = 1; i < 20; i++){ pow[i] = pow[i - 1] * 3; } while (1){ scanf("%d%d", &n, &m); if (n + m == 0){ break; } memset(start.tower, 0, sizeof(start.tower)); for (i = 0; i < 3; i++){ scanf("%d", &start.t[i]); for (j = 0; j < start.t[i]; j++){ scanf("%d", &start.tower[i][j]); } } memset(v, 0, sizeof(v)); start.time = 0; head = tail = 0; pw = pow[n] - 1; enq(start); while (head != tail){ deq(&temp); if (temp.time > m){ printf("-1\n"); break; } if (move(temp, 0, 1, pw)){ break; } if (move(temp, 1, 0, pw)){ break; } if (move(temp, 1, 2, pw)){ break; } if (move(temp, 2, 1, pw)){ break; } } } return (0); }
2011-12-13 23:06
nice!(0)
コメント(0)
トラックバック(0)
コメント 0