一. 原题链接 http://poj.org/problem?id=3740
二. 思路:
1、直接DFS搜,然后记得把cin cout改成 scanf printf。就不会超时。这道题告诉我们分函数写的重要性。
2、跳舞链,多么优雅名字,写了好久的,然后为什么我写完之后,提交后的时间比DFS多呢。是我太弱了吧- -!
三. 代码
DFS 610ms
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <vector> #include <string> using namespace std; int square[30][500], row, col, mark[500]; int cntMark; int rememberJ[302]; bool OK; bool checkRow(int i) { for(int j = 0; j < col; j++){ if(square[i][j] && mark[j]) return false; } return true; } //return the last index which is marked; int markRow(int i) { int j; for(j = 0; j < col; j++){ if(square[i][j]){ cntMark++; mark[j] = true; } } return j - 1; } void disMark(int i, int j) { for(; j >= 0; j--){ if(square[i][j]){ cntMark--; mark[j] = false; } } } void dfs(int i, int j) { if(col == cntMark){ OK = true; return; } if(i == row || OK) return ; for(; i < row; i++){ if(checkRow(i)){ int preMark = markRow(i); dfs(i + 1, preMark + 1); disMark(i, preMark); } } } int main() { // freopen("in.txt", "r", stdin); int i, j; while(scanf("%d%d", &row, &col) != EOF){ for(i = 0; i < row; i++) for(j = 0; j < col; j++) scanf("%d", &square[i][j]); memset(mark, 0, sizeof(mark)); cntMark = 0; OK = false; dfs(0, 0); if(OK) printf("Yes, I found it\n"); else printf("It is impossible\n"); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <vector> #include <string> using namespace std; const int m = 18, n = 305; struct node { node *l, *r, *u, *d; int IdOfCol, IdOfRow; }; node heap[m * n], *C[n], *head = NULL; int row, col, top; node *newNode() { return &heap[top++]; } void init() { top = 0; head = newNode(); int j; for(j = 1; j <= col; j++){ C[j] = newNode(); } for(j = 1; j <= col; j++){ C[j]->l = C[j-1]; C[j]->r = C[j+1]; C[j]->d = C[j]->u = C[j]; C[j]->IdOfCol = j; } head->IdOfCol = 0; head->l = C[col]; head->r = C[1]; C[1]->l = head; C[col]->r = head; } void del(node *C) { C->l->r = C->r; C->r->l = C->l; node *i, *j; for(i = C->d; i != C; i = i->d){ for(j = i->r; j != i; j = j->r){ j->u->d = j->d; j->d->u = j->u; } } } void resume(node *C) { C->l->r = C; C->r->l = C; node *i, *j; for(i = C->d; i != C; i = i->d){ for(j = i->r; j != i; j = j->r){ j->u->d = j; j->d->u = j; } } } bool dfs() { node *cur = head->r, *i, *j; if(cur == head) return true; for(i = cur->d; i != cur; i = i->d){ del(cur); for(j = i->r; j != i; j = j->r){ del(C[j->IdOfCol]); } if(dfs()) return true; resume(cur); for(j = i->r; j != i; j = j->r){ resume(C[j->IdOfCol]); } } return false; } int main() { //freopen("in.txt", "r", stdin); int i, j, buffer; while(scanf("%d%d", &row, &col) != EOF){ init(); for(i = 1; i <= row; i++){ node *p = NULL, *s = NULL; for(j = 1; j <= col; j++){ scanf("%d", &buffer); if(1 == buffer){ p = newNode(); if(!s) p->l = p->r = p; else p->l = s, p->r = s->r, s->r->l = p, s->r = p; s = p; p->d = C[j]; p->u = C[j]->u; C[j]->u->d = p; C[j]->u = p; p->IdOfCol = j; p->IdOfRow = i; } } } if(dfs()) printf("Yes, I found it\n"); else printf("It is impossible\n"); } return 0; }