poj——3740 Easy Finding
2016-06-08 15:24
253 查看
POJ - 3740 Easy Finding
Description Given a M× N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn contains and only contains one 1. Input There are multiple cases ended by EOF. Test case up to 500.The first line of input is M, N ( M ≤ 16, N ≤ 300). The next M lines every line contains Nintegers separated by space. Output For each test case, if you could find it output "Yes, I found it", otherwise output "It is impossible" per line. Sample Input 3 3 0 1 0 0 0 1 1 0 0 4 4 0 0 0 1 1 0 0 0 1 1 0 1 0 1 0 0 Sample Output Yes, I found it It is impossible Source POJ Monthly Contest - 2009.08.23, MasterLuo 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矩阵还是挺烦的。。 |
相关文章推荐
- Python-Socket
- 《程序员修炼之道--从小工到专家》阅读笔记01
- Win8下设置NotePad++和TortiseSVN集成
- CADisplayLink以及定时器的使用
- 解决Access32位驱动器问题
- axi dma Scatter/Gsther list 描述符
- 数据结构—基于广度优先遍历算法的应用
- w系统负载,free
- python随机生成字符
- Codevs 1432 总数统计
- C# 后台json转换成时间格式
- Android图片占据的内存大小分析
- HTML代码规范
- Python-嵌套列表list的全面解析
- 负载均衡器技术Nginx和F5的优缺点对比
- 第15周阅读程序(5)
- Joining data
- SHELL编程之语法基础
- EasyUI 第一个demo
- 机器学习--SVM分类器