一. 原题链接 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;
}
跳舞链810ms
#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;
}