http://poj.org/problem?id=3740

这是一道搜索+回溯的题目,也是我第一次接触到回溯。

题意就是找一些行,这些行可以使每一列都只存在一个1。

深搜加回溯:

memory:118K c++ runtime:674ms。
#include <stdio.h>
#include <string.h>
#include <iostream> using namespace std; int a[][],n,m;
bool used[],fin; bool judge() //判断是否已经寻找到那些行加起来可以使所有的列只存在一个1。
{
for(int i=;i<=m;i++)
if(!used[i]) return false;
return true;
}
bool check(int row) //判断当前行是否有与之前行在某一列有冲突(都有1)
{
for(int i=;i<=m;i++)
if(used[i]&&a[row][i]) return false; // 如果都有1的话,回溯。
for(int i=;i<=m;i++)
if(a[row][i]) used[i]=true; //如果不冲突的话,则把这一行用上,并把其的所有的1所在的行都标记上。
return true;
} void dfs(int s)
{
if(fin||s>n+) return; //判断退出的标志,即输出的结果,或者行数已经超过了n+1。
if(judge()) {
printf("Yes, I found it\n");
fin=true;
return;
}
for(int i=s;i<=n&&!fin;i++)
{
if(check(i)){
dfs(i+);    
for(int j=;j<=m;j++) //这就是回溯,因为如果I+1与之前的有冲突的话,if(check(i+1))则为false。所以执行的就应该是这一行。
if(a[i][j]) used[j]=false;
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(a,,sizeof(a));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&a[i][j]);
fin=false;
memset(used,false,sizeof(used));
dfs();
if(!fin) printf("It is impossible\n");
}
return ;
}

最新文章

  1. ubuntu安装
  2. Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系
  3. Servlet的配置
  4. kb
  5. python __init__.py用途
  6. Spring之在客户端访问RESTful业务
  7. 【HDOJ】1495 非常可乐
  8. KnockOutJS学习系列----(一)
  9. Android 通过HTTP GET请求互联网数据
  10. STL之queue(单向队列)
  11. CMDeviceMotion使用
  12. VS2015企业版本(安装包+key)
  13. PHP运算符知识点
  14. 【Java数据结构学习笔记之二】Java数据结构与算法之队列(Queue)实现
  15. ES6 对象的扩展(上)
  16. 细说java系列之泛型
  17. 微信小程序 this.data与this.setData
  18. angular学习笔记(三十)-指令(9)-一个简单的指令示例
  19. 【339】matplotlib based on python3
  20. andriod sdk 安卓模拟器修改imei码,位置信息

热门文章

  1. SQL之按两个字段分类汇总
  2. Linq 中的 left join
  3. JaxWsProxyFactoryBean 与 JaxWsDynamicClientFactory
  4. 网络方案 &amp; HTTP状态码
  5. ajava包的命名
  6. oracle 中的Ipad()函数
  7. readline
  8. 从一个弱引用导致的奔溃 谈 weak assign strong的应用场景【iOS开发教程】
  9. nyoj 4 ASCII码排序 java
  10. PHP文件的上传与下载