Easy Finding
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 15668   Accepted: 4163

Description

Given a M×N matrix AAij ∈ {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 MN (M ≤ 16, N ≤ 300). The next M lines every line contains N integers 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

  1. 3 3
  2. 0 1 0
  3. 0 0 1
  4. 1 0 0
  5. 4 4
  6. 0 0 0 1
  7. 1 0 0 0
  8. 1 1 0 1
  9. 0 1 0 0

Sample Output

  1. Yes, I found it
  2. It is impossible

Source

题意:

给你一个n*m(n<=16,m<=300)的矩阵。矩阵的每一个元素仅仅能是0或1.如今问你能不能从里面选一些列出来使的没一列有且仅有一个1.

思路:

開始逗比了。把题看成每行仅仅有16个。一看16就乐了。这是典型的壮压嘛。

把每行压成长度为16的二进制数。

然后就是可行性判定了。写完一交re了。

这还用说。

m,n都看错了不re才怪。因为每行值个数太多。不能壮压了。无赖。仅仅能百度。得知是Dancing Links.于是百度其资料。

链接一枚

具体见代码:

  1. #include<iostream>
  2. #include<stdio.h>
  3. using namespace std;
  4. const int INF=0x3f3f3f3f;
  5. const int maxn=6010;
  6. int U[maxn],D[maxn],L[maxn],R[maxn],C[maxn];//上下左右指针。
  7.  
  8. c[i]结点i相应的列。
  9. int S[310],H[310];//S[i]为i列1的个数。H[i]为i行的尾指针。
  10.  
  11. int n,m,cnt;
  12. void init()
  13. {
  14. int i;
  15. for(i=1;i<=n;i++)
  16. H[i]=-1;
  17. for(i=0;i<=m;i++)
  18. {
  19. S[i]=0;
  20. L[i+1]=i;
  21. R[i]=i+1;
  22. U[i]=D[i]=i;
  23. }
  24. R[m]=0;
  25. cnt=m+1;
  26. }
  27. void Insert(int r,int c)
  28. { //头插法建链表
  29. U[cnt]=c,D[cnt]=D[c];//确定新增结点上下指针信息
  30. U[D[c]]=cnt,D[c]=cnt;//恢复链表信息
  31. if(H[r]==-1) //确定左右指针信息
  32. H[r]=L[cnt]=R[cnt]=cnt;//增加头
  33. else
  34. {
  35. L[cnt]=H[r],R[cnt]=R[H[r]];//头插法
  36. L[R[H[r]]]=cnt,R[H[r]]=cnt;
  37. }
  38. S[c]++;//更新附加信息
  39. C[cnt++]=c;
  40. }
  41. void Remove(int c)//移除c列。
  42.  
  43. {
  44. int i,j;
  45. R[L[c]]=R[c],L[R[c]]=L[c];
  46. for(i=D[c];i!=c;i=D[i])
  47. for(j=R[i];j!=i;j=R[j])
  48. D[U[j]]=D[j],U[D[j]]=U[j],S[C[j]]--;
  49. }
  50. void Resume(int c)//还原c列。
  51.  
  52. {
  53. int i,j;
  54. R[L[c]]=L[R[c]]=c;
  55. for(i=D[c];i!=c;i=D[i])
  56. for(j=R[i];j!=i;j=R[j])
  57. D[U[j]]=U[D[j]]=j,S[C[j]]++;
  58. }
  59. bool dfs()
  60. {
  61. if(R[0]==0)
  62. return true;
  63. int i,j,c,miv=INF;
  64. for(i=R[0];i;i=R[i])
  65. if(S[i]<miv)
  66. miv=S[i],c=i;
  67. Remove(c);//处理第c列
  68. for(i=D[c];i!=c;i=D[i])
  69. {
  70. for(j=R[i];j!=i;j=R[j])
  71. Remove(C[j]);
  72. if(dfs())
  73. return true;
  74. for(j=L[i];j!=i;j=L[j])
  75. Resume(C[j]);
  76. }
  77. Resume(c);
  78. return false;
  79. }
  80. int main()
  81. {
  82. int op,i,j;
  83. while(~scanf("%d%d",&n,&m))
  84. {
  85. init();
  86. for(i=1;i<=n;i++)
  87. for(j=1;j<=m;j++)
  88. {
  89. scanf("%d",&op);
  90. if(op)
  91. Insert(i,j);
  92. }
  93. if(dfs())
  94. printf("Yes, I found it\n");
  95. else
  96. printf("It is impossible\n");
  97. }
  98. return 0;
  99. }

poj 3740 Easy Finding(Dancing Links)的更多相关文章

  1. [ACM] POJ 3740 Easy Finding (DLX模板题)

    Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16178   Accepted: 4343 Des ...

  2. poj 3740 Easy Finding 二进制压缩枚举dfs 与 DLX模板详细解析

    题目链接:http://poj.org/problem?id=3740 题意: 是否从0,1矩阵中选出若干行,使得新的矩阵每一列有且仅有一个1? 原矩阵N*M $ 1<= N <= 16 ...

  3. [ACM] POJ 3740 Easy Finding (DFS)

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16202   Accepted: 4349 Description Give ...

  4. poj 3740 Easy Finding 精确匹配

    题目链接 dlx的第一题, 真是坎坷..... #include <iostream> #include <vector> #include <cstdio> #i ...

  5. POJ 3740 Easy Finding

    #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using ...

  6. POJ 3074 Sudoku (Dancing Links)

    传送门:http://poj.org/problem?id=3074 DLX 数独的9*9的模板题. 具体建模详见下面这篇论文.其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中 ...

  7. Easy Finding POJ - 3740 (DLX)

    显然这是一道dfs简单题 或许匹配也能做 然而用了dancing links 显然这也是一道模板题 好的吧 调了一上午 终于弄好了模板 Easy Finding Time Limit: 1000MS ...

  8. 【POJ 3740】 Easy Finding

    [题目链接] http://poj.org/problem?id=3740 [算法] Dancing Links算法解精确覆盖问题 详见这篇文章 : https://www.cnblogs.com/g ...

  9. POJ 3740 Dancing Links

    Dancing Links学习:http://www.cnblogs.com/steady/archive/2011/03/15/1984791.html 以及图文学习:http://www.cnbl ...

随机推荐

  1. js冒泡法和数组转换成字符串示例代码

    将数组转换成字符串的方法有很多,讲解下js冒泡法的使用.js代码: //js冒泡法与数据转换为字符串的例子 //整理:www.jbxue.com window.onload = function(){ ...

  2. PHP5.5四种序列化性能对照

    json_encode,serialize,igbinary,msgpack四种序列化方式,在之前已经有过相关的測试,PHP5.5这方面的測试临时没有,这次測试基于PHP5.5,而且測试用例,http ...

  3. haproxy 配置mysql的代理

    应用场境,是如果mysql服务器没有外网的,需要一个有外网的代理服务器做代理,这时就可以用haproxy做个四层的代理: listen mysql bind mode tcp balance roun ...

  4. 如何使用Redis做MySQL的缓存

    应用Redis实现数据的读写,同时利用队列处理器定时将数据写入mysql. 同时要注意避免冲突,在redis启动时去mysql读取所有表键值存入redis中,往redis写数据时,对redis主键自增 ...

  5. Mixing ASP.NET Webforms and ASP.NET MVC

    https://www.packtpub.com/books/content/mixing-aspnet-webforms-and-aspnet-mvc *********************** ...

  6. django 线上线下使用不同的数据库 上线:mysql 线下sqlite3 以及debug模式的开和关

    hostname = socket.gethostname() 获取主机名称 import os import socket hostname = socket.gethostname() if ho ...

  7. C++控制台读取和输出函数

    c中puts()函数用来向标准输出设备(屏幕)写字符串并换行,其调用方式为,puts(s);其中s为字符串字符(字符串数组名或字符串指针). 功 能: 送一字符串到流stdout中 用 法: int ...

  8. 基于jQuery图像碎片切换效果插件FragmentFly

    基于jQuery图像碎片切换效果插件FragmentFly.这是一款只需三步轻松完成碎片动画,参数可调,使用方便. 在线预览   源码下载 部分代码: <div class="all_ ...

  9. C语言 · 实现strcmp函数 · 字符串比较

    蓝桥杯练习场上碰到两个此类题了: 算法提高 11-1实现strcmp函数   时间限制:1.0s   内存限制:256.0MB      问题描述 自己实现一个比较字符串大小的函数,也即实现strcm ...

  10. pthread_self()究竟根据什么来得到线程的标识符????

    #include<stdlib.h> #include<pthread.h> #include<stdio.h> #include<sched.h> # ...