DLX的纯模板题,,只不过一开始各种TLE。。
第一个是使用scanf,,
第二个是使用输入挂
第三个是关闭了输入同步的cin。。结果奇异的TLE了,,不科学啊,,scanf才260多ms。。
第4个是刺果果的cin。。。
#include <stdio.h>
#include <iostream>
#include<math.h>
#include<stack>
#include<algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
bool _map[300+5][300+5];
int id[300+5][300+5];
int n,m,cnt;
//stack<int> ans;
struct Node {
int _up,_down,_left,_right,x,y;
} node[10000+100];
//构造舞蹈链
void Build() {
node[0]= {0,0,0,0,0,0};
cnt++;
int pre=0;
for(int i=1; i<=m; i++) {
cnt++;
//初始化x,y坐标
node[i].x=0;
node[i].y=i;
node[i]._up=node[i]._down=i;
node[i]._right=node[pre]._right;
node[i]._left=pre;
node[node[pre]._right]._left=i;
node[pre]._right=i;
pre=i;
}
//初始化节点
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(_map[i][j]) {
id[i][j]=cnt;
node[cnt]= {cnt,cnt,cnt,cnt,i,j};
cnt++;
}
//纵向加节点
for(int i=1; i<=m; i++) {
int pre=i;
for(int j=1; j<=n; j++) {
if(_map[j][i]) {
int p=id[j][i];
node[p]._down=node[pre]._down;
node[p]._up=pre;
node[node[pre]._down]._up=p;
node[pre]._down=p;
pre=p;
}
}
}
//横向加节点
for(int i=1; i<=n; i++) {
int pre=-1;
for(int j=1; j<=m; j++) {
if(_map[i][j]) {
if(pre==-1) pre=id[i][j];
else {
int p=id[i][j];
node[p]._right=node[pre]._right;
node[p]._left=pre;
node[node[pre]._right]._left=p;
node[pre]._right=p;
pre=p;
}
}
}
}
}
void Remove(int x) {
node[node[x]._left]._right=node[x]._right;
node[node[x]._right]._left=node[x]._left;
int p1=node[x]._down;
while(p1!=x) {
int p2=node[p1]._right;
while(p2!=p1) {
node[node[p2]._up]._down=node[p2]._down;
node[node[p2]._down]._up=node[p2]._up;
p2=node[p2]._right;
}
p1=node[p1]._down;
}
}
void Resume(int x) {
node[node[x]._left]._right=x;
node[node[x]._right]._left=x;
int p1=node[x]._down;
while(p1!=x) {
int p2=node[p1]._right;
while(p2!=p1) {
node[node[p2]._up]._down=p2;
node[node[p2]._down]._up=p2;
p2=node[p2]._right;
}
p1=node[p1]._down;
}
}
bool dance() {//开始跳舞~~
int p1=node[0]._right;
if(p1==0) return true;
int p2=node[p1]._down;
if(p2==p1) return false;
Remove(node[p1].y);
while(p2!=p1) {
//ans.push(node[p2].x);
int p3=node[p2]._right;
while(p3!=p2) {
Remove(node[p3].y);
p3=node[p3]._right;
}
if(dance()) return true;
//恢复
p3=node[p2]._left;
while(p3!=p2) {
Resume(node[p3].y);
p3=node[p3]._left;
}
p2=node[p2]._down;
}
Resume(node[p1].y);
return false;
}
int read() { //输入外挂
int res=0,ch,flag=0;
if((ch=getchar())=='-')flag=1;
else if(ch>='0'&&ch<='9') res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0';
return flag?-res:res;
}
int main() {
//freopen("input.txt","r",stdin);
while(~scanf("%d%d",&n,&m)) {
cnt=0;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) _map[i][j]=read();
Build();
printf("%s\n",dance()?"Yes, I found it":"It is impossible");
}
return 0;
}
DLX能解决很多奇怪的问题,N皇后,数独,
伤脑筋十二块,等等,,。。
不过,,怎么将一道题构建成这么一个01矩阵还是挺烦的。。