uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1259
压缩Panel的全部状态,预处理出每个位置的变化,然后dfs搜索全部情况。不过这样是会超时的,所以我在搜索的过程中加上剪枝,预判出之前的状态是否能够使得最后整个Panel充满,如果不能就尽早跳出搜索。加上小小的一个剪枝,速度提升估计了不下1000倍,由原来的超时,最后只要0.008s就完成了!
代码如下:
View Code
1 #define REP(i, n) for (int i = 0; i < (n); i++) 2 #define REP_1(i, n) for (int i = 1; i <= (n); i++) 3 4 const int dir[9][2] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 0}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; 5 char buf[3][4]; 6 LL pat[25], ok[6]; 7 8 void pntPat(LL n) { 9 printf("~~~~~ %lld ~~~~~~\n", n); 10 DEC(i, 63, 0) { 11 if (n & (1ll << i)) putchar('1'); 12 else putchar('0'); 13 if ((i & 7) == 0) puts(""); 14 } 15 } 16 17 void makePat(int n, int m) { 18 int t = (1 << m) - 1 << 1; 19 REP(i, n + 1) { 20 ok[i] = 0; 21 REP(j, i) { 22 ok[i] |= t; 23 ok[i] <<= 8; 24 } 25 // pntPat(ok[i]); 26 } 27 REP(i, n) { 28 REP(j, m) { 29 int id = i * m + j; 30 pat[id] = 0; 31 REP(k, 9) { 32 int x = dir[k][0] + i + 1, y = dir[k][1] + j + 1; 33 if (buf[k / 3][k % 3] == '*') pat[id] |= 1ll << x * 8 + y; 34 } 35 // cout << id << endl; 36 // pntPat(pat[id]); 37 } 38 } 39 } 40 41 int rec[30], cnt; 42 43 bool dfs(LL cur, int pos, int end, int n, int m) { 44 if ((cur & ok[n]) == ok[n]) return true; 45 if (pos >= end) return false; 46 int t = pos / m - 1; 47 // cout << pos << ends << m << ends << t << endl; 48 if (t > 0 && (cur & ok[t]) != ok[t]) return false; 49 if (dfs(cur, pos + 1, end, n, m)) return true; 50 rec[cnt++] = pos + 1; 51 if (dfs(cur ^ pat[pos], pos + 1, end, n, m)) return true; 52 cnt--; 53 return false; 54 } 55 56 void work(int n, int m) { 57 makePat(n, m); 58 cnt = 0; 59 if (dfs(0, 0, n * m, n, m)) { 60 REP(i, cnt) { 61 if (i) putchar(' '); 62 printf("%d", rec[i]); 63 } 64 puts(""); 65 } else { 66 puts("Impossible."); 67 } 68 } 69 70 int main() { 71 // freopen("in", "r", stdin); 72 int n, m, cas = 1; 73 while (~scanf("%d%d", &n, &m) && (n || m)) { 74 REP(i, 3) scanf("%s", buf[i]); 75 printf("Case #%d\n", cas++); 76 work(n, m); 77 } 78 return 0; 79 }
——written by Lyon