#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
//#define INPUT
/**
Problem: poj3740 - Easy Finding
Begin Time:8:30 p.m. 20th/Mar/2012
End Time: 8:42 p.m. 21st/Mar/2012
Last Time: Maybe 4hours-;
Input:
Standard output:
Knowledge point:
DFS+回溯+剪枝
State: WA x 1 , TLE x 1 -> AC
Thought:
--------------------AC后的总结----------------------
1.定义一个数组selectedCol,表示目前选出了几列中有"1".
2.在choose之前,要检查selectedRow[i]是否为true.
如果是true,这行就选过了,就continue
3.在每次choose某行的时候,都在choose函数里进行check
if choose_row[i] == 1 && selectedCol[i] == 1 return false;
if choose_row[i] && !selectedCol[i] => selectedCol[i] = 1;
但是在choose之前记得保存selectedCol的状态,以便return false之前进行回溯。
4.如果choose失败的话,就要检查是否已经找到了全1,如果找到了
isFound = true;
在递归函数里检查isFound = true的话就return true;
5.如果没找到的话,记得回溯。这就要求在递归函数里每次保存selectedCol的状态,失败了进行回溯。
6.如果leftRow == 0 ,那么就check,如果check,return true;,否则return false;
剪枝策略:
每层递归都是从 i = 0 to rowNum 开始选
如果上层递归选了i,那就下层递归从i+1开始选。
因为上层递归从0开始选,选到i的话[0,i]的情况已经由上层递归选完了。
而且行数跟顺序无关
比如说
第一层递归选了1
那么第二,第三……一直到最后一层递归,肯定是把第一次选1的所有情况都遍历了,
第一层递归才能去选2
而且
1 2 3 4 5 6
和
6 5 4 3 2 1
这么选择是没有区别的,所以下一层递归从ind+1开始就可以了
加上这个剪枝,653ms就过了。
更变态的思路:
由于是0,1我们可以按位表示嘛!然后按照规则算,应该会非常快~
递归函数定义:
f(int totalRow,int totalCol,int leftRow,int ind);
totalRow表示总共有多少行
totalCol表示列数
leftRow表示还有几行没选
int ind表示从现在第几行开始选。
--------------------AC前的涂鸦----------------------
其实这道题跟STICK是差不多的,当然,状态压缩是必须的。
每行压缩成一个数字,然后是否有几个数字相加起来正好等于
1111111....
注意,最多可以有10^300,所以这个比较囧!
每一个状态就是按行i是否被选择来决定,
选择了某一行之后,就定义tmp[m]对应的列已经被占领。
那么剩下的就转化为用leftNum - 1行来拼出来其他的列了,如果都能拼出来,那么
return true,否则return false;
定义函数f(rowNum,colNum,leftNum);表示总共有rowNum列,有colNum行,剩leftNum没有选
每次选择的时候定义一个check,看看是否已经选出了每列全有1的行。
还有一个check2,看看当前选的行是否跟以前的行有冲突。
**/
using namespace std;
int matrix[20][310]; ///开大一点总是没错的
bool selectedCol[310];
bool selectedRow[18];
bool isFound;
bool checked(const int colNum)
{
for(int i = 0 ; i < colNum ; i++)
{
if (!selectedCol[i])
return false;
}
return true;
}
bool choose(const int a[310],int colNum)
{
int tmp_state[310];
memset(tmp_state,0,sizeof(tmp_state));
memcpy(tmp_state,selectedCol,sizeof(tmp_state));
for(int i = 0 ; i < colNum ; i++)
{
if(!selectedCol[i] && a[i] )
{
selectedCol[i] = a[i];
}
else
{
if ( selectedCol[i] && a[i] )
{
memcpy(selectedCol,tmp_state,sizeof(tmp_state));
return false;
}
}
}
return true;
}
bool Solve(int rowNum,int colNum,int leftNum,int ind)
{
int tmp_state[310];
memset(tmp_state,0,sizeof(tmp_state));
if( isFound )
return true;
if (leftNum == 0)
{
if ( checked(colNum) )
{
isFound = true;
return true;
}
else
{
return false;
}
}
for(int i = ind ; i < rowNum ; i++)
{
memcpy(tmp_state,selectedCol,sizeof(tmp_state));
if( isFound ) return true;
if ( selectedRow[i] ) continue;
if ( choose(matrix[i],colNum) )
{
if( selectedRow[i] != true && !checked(colNum) )
{
selectedRow[i] = true;
Solve(rowNum,colNum,leftNum - 1,i+1);
}
else
{
if ( checked(colNum) )
{
isFound = true;
return true;
}
}
// memcpy(matrix[i],tmp_state,sizeof(tmp_state));
memcpy(selectedCol,tmp_state,sizeof(selectedCol));
selectedRow[i] = false;
}
// selectedRow[i] = false;
}
return false;
}
int main()
{
int n,m;
#ifdef INPUT
freopen("b:\\acm\\poj3740\\input.txt","r",stdin);
#endif
while(scanf("%d%d",&m,&n) != EOF )
{
isFound = false;
memset(matrix,0,sizeof(matrix));
memset(selectedCol,0,sizeof(selectedCol));
memset(selectedRow,0,sizeof(selectedRow));
for(int i = 0 ; i < m ; i++)
{
for(int j = 0 ; j < n ; j++)
{
scanf("%d",&matrix[i][j]);
}
}
if ( Solve(m,n,m,0) )
{
printf("Yes, I found it\n");
}
else
{
printf("It is impossible\n");
}
}
return 0;
}
相关推荐
保姆级教程:用海思PQTool搞定ISP图像调试,从参数读取到固件烧录全流程
本文提供海思PQTool的ISP图像调试全流程指南,从参数读取、实时调试到固件烧录,涵盖环境配置、核心功能解析、参数固化及生产部署。通过实战案例和避坑指南,帮助开发者高效提升图像质量,适用于海思开发板的ISP调试与优化。
POJ-3740-Easy Finding【DLX精确覆盖】
POJ-3740-Easy Finding
别再为电路自激发愁了:手把手教你用吸波材料搞定微波腔体谐振(附HFSS仿真设置)
本文详细解析了微波腔体谐振问题的工程解决方案,重点介绍了吸波材料的选型、安装工艺及HFSS仿真设置。通过实际案例和计算工具,帮助射频工程师有效抑制腔体自激,提升系统稳定性。特别适用于35GHz毫米波雷达等高频电路设计场景。
poj 3740 Easy Finding
题意:给一个01矩阵,问是否能找到一个行的集合,使得集合中每列出现且仅出现一次‘1’。 思路:舞蹈链X算法模版题。来谈谈我对这个算法的理解。。这个算法是一个深搜,但是它的数据结构非常巧妙,是一个循环十字链表,把矩阵内为1的元素建立节点,都链起来,还加上了一个“表头”。每次先选一列没找到‘1’的列,如果没有,则寻找失败;如果有,选择一行,把这行,这行有‘1’的列,与这行有公共列出现
WIN下使用visual studio 2022安装GMSSL命令行工具
2.1 使用管理员权限打开visual studio(非常重要,否则最后一步 nmake install会失败)右键vs2022,以管理员身份运行即可。2.4 配置环境变量,gmssl可执行程序默认会被安装到如下目录。将如下路径添加到系统环境变量即可。添加后的环境变量如下。2.编译解压后的gmssl源码,编译过程主要参考install.md中的内容,README.md中的步骤不完整。2.2 打开vs2022的命令终端,右键文件,选择在终端中打开。1.下载gmssl源码,解压到相应目录。
告别环境配置噩梦:VSCode + MinGW 下 OpenGL (glad/glm/glfw) 一站式配置指南(含常见错误排查)
本文提供了一份详细的VSCode与MinGW下OpenGL开发环境配置指南,涵盖glad、glm和glfw三大核心库的安装与调试。通过逐步指导解决常见错误,帮助开发者快速搭建高效的OpenGL开发环境,特别适合初学者避免环境配置中的常见陷阱。
POJ 3740 Easy Finding(DLX精确覆盖裸题)
POJ 3740 Easy Finding 题目链接 题意:选一些行,要求每行正好覆盖一个列 思路:精确覆盖裸题 代码: #include #include using namespace std; const int MAXNODE = 500010; const int MAXN = 510; const int MAXM = 1010; const i
PyQtWebEngine安装避坑指南:快速解决ModuleNotFoundError
本文详细解析了PyQt5开发中常见的ModuleNotFoundError: No module named 'PyQt5.QtWebEngineWidgets'错误。核心原因是PyQt5 5.11版本后,网页引擎组件被独立为PyQtWebEngine包。文章对比了退回旧版本、独立安装及使用Conda等多种解决方案,并提供了针对Windows、macOS和Linux不同平台的实战安装指南与验证方法,帮助开发者快速解决依赖问题。
POJ 3740 Easy Finding(精确覆盖模板题)
题目大意 给定一个M*N的01矩阵,能否找到一个行的集合,使得集合中每一列都恰好包含一个1。
【Diffusion分割】医学图像分割中去噪扩散技术
扩散模型(DPM)在图像生成方面表现出了卓越的性能,其性能往往优于其他生成模型。自其问世以来,强大的噪声-图像去噪管道已被扩展到各种判别任务中,包括图像分割。在医学成像中,图像往往是大型三维扫描图像,由于内存消耗大、迭代采样过程耗时,使用 DPM 对一幅图像进行分割的效率极低。在这项工作中,我们提出了一种(LDSeg),可在潜空间中执行扩散,用于医学影像分割。我们。潜空间条件扩散不仅能确保对多标签对象进行精确的 n-D 图像分割,还能缓解基于 DPM 的传统分割法的主要潜在问题:(。
pycharm一直选择不了conda正确路径弹框报错:latinit property envs_dirs has not been initialized...如何解决?
🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。
POJ3740-Easy Finding
#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define LL long long const int INF =
腾讯音乐 QQ音乐商业化客户端开发工程师:岗位深度解析与面试攻略
腾讯音乐QQ音乐商业化客户端开发工程师岗位要求3年以上Android开发经验,熟练掌握Kotlin/Java及跨端开发技术。核心职责包括QQ音乐客户端功能开发、架构优化、性能提升及技术攻关。岗位要求计算机相关本科以上学历,具备完整项目开发经验,熟悉TCP/IP等网络协议,能独立解决复杂技术问题。面试重点考察项目经验、架构设计、性能优化及新技术研究能力,建议候选人准备具体案例,量化成果,并熟悉Flutter等跨端技术。该职位强调技术深度与产品思维的结合,需展现扎实的编程基础、问题解决能力和团队协作精神。
[ACM] POJ 3740 Easy Finding (DFS)
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16482 Accepted: 4476 Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), co
Devexpress16.2.6破解工具
Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具
android 蓝牙通讯demo
android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。
[poj3740]Easy Finding_状态压缩_dfs
Easy Finding poj-3470 题目大意:给你一个01矩阵,问能否选出一些行,使得这些行所新组成的01矩阵每列中有且只有1个1。 注释:1<=行数<=16,1<=列数<=300. 想法:对于一个单独的01矩阵来讲,我们可以用一个数表示其中的每一行,然后暴力枚举每一行选取情况即可。 最后,附上丑陋的代码... ... ...
visio安装包
Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。
poj 3740 Easy Finding(Dancing Links)
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15668 Accepted: 4163 Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i Input There ar
汉书HE8,好用的汇编代码编写工具
汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大
poj3740 Easy Finding(深搜)
Easy FindingTime Limit: 1000MS Memory Limit: 65536KTotal Submissions: 11432 Accepted: 2802DescriptionGiven a M×N matrix A. Aij ∈ {
POJ 3740 Easy Finding(舞蹈链)
/* 舞蹈链模板题 */ #include #include const int mMax = 50, nMax = 500; int map[mMax][nMax]; int M, N; struct Node { int left, right, up, down; int col; }node[mMax * nMax];//双向链表 int len; int cnt[nMax];
POJ 3740 Easy Finding 跳舞链模板
题目:http://poj.org/problem?id=3740题意:给出一个n∗mn*m的0101矩阵,问能不能够选出来若干行,使每列恰好只有一个11思路:跳舞链模板题。代码中其实把方案记录在ans数组中,要方案的话打印ans数组即可#include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using
POJ 3740 Easy Finding 位运算压缩+DFS or Dancing Links
Easy Finding 这道题运用二进制DFS是比较好的方法,当然还可以用dancing links,这个比较高级,先把我看别人的二进制思路然后写的代码贴上来。 当然本题是体现不出DLX的高级之处的。用位运算和DLX的速度应该是相当 /* ID: sdj22251 PROG: calfflac LANG: C++ */ #include #include #include #in
[ACM] POJ 3740 Easy Finding (DLX模板题)
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16178 Accepted: 4343 Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), co
poj 3740 Easy Finding(Dancing Links 精确覆盖)
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16128 Accepted: 4321 Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), co
POJ 3740 Easy Finding (DLX)
题意:精确覆盖,DLX模板题思路:这个博客写的不错 刚刚开学DLX,感觉是个很简单的东西,只能算是十字链表优化了DFS,所以理论上有些DLX题目的有些题目应该DFS也能水过去 去看板子,发现所有人的板子都几乎一模一样。。。错误及反思:代码:#include <iostream> #include <stdio.h> #include <string.h>const int MN = 1005;/
POJ 3740 Easy Finding 位运算压缩+DFS
Easy Finding 这道题运用二进制DFS是比较好的方法,当然还可以用dancing links,这个比较高级,先把我看别人的二进制思路然后写的代码贴上来。 /* ID: sdj22251 PROG: calfflac LANG: C++ */ #include <iostream> #include <vector> #include <list>...
POJ-3740(dfs边界点和还原处理)(Easy Finding)
【题目描述】 选出一些行使得这些行构成矩阵的每一列都有且只有一个1。 【接替思路】 直接判断每一行是否选中。 此方法并不高效。 int m, n; int Map[16][300]; bool used[300]; bool Find; bool match()//判断所选取的行是否让每一列都恰好有一个1 { int i; for (i = 0; i < n; ++i) if
POJ3740--Easy Finding(Dancing Links)
Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i 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 e
281



被折叠的 条评论
为什么被折叠?



