#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;
}
相关推荐
BQ4050开发进阶(二):Protections参数优化策略与实战解析
本文深入解析了BQ4050电池管理芯片中Protections参数的优化策略与实战方法。针对电压、电流、温度等核心保护功能,详细阐述了如何根据具体电芯特性、负载场景和环境因素,精细调整CUV、COV、OCC/OCD等阈值与延时,以在确保电池绝对安全的前提下,实现极致的用户体验与系统可靠性。
POJ-3740-Easy Finding【DLX精确覆盖】
POJ-3740-Easy Finding
手把手教你用SIMCOM A7670C_FASL模组实现双路MQTT连接阿里云(附完整源码)
本文详细介绍了如何使用SIMCOM A7670C_FASL 4G模组实现双路MQTT连接阿里云,包括硬件配置、开发环境搭建、双路MQTT架构设计及实现细节。通过完整的源码示例和实战指南,帮助开发者快速掌握物联网设备开发中的多路MQTT连接技术,提升工业级应用的开发效率。
poj 3740 Easy Finding
题意:给一个01矩阵,问是否能找到一个行的集合,使得集合中每列出现且仅出现一次‘1’。 思路:舞蹈链X算法模版题。来谈谈我对这个算法的理解。。这个算法是一个深搜,但是它的数据结构非常巧妙,是一个循环十字链表,把矩阵内为1的元素建立节点,都链起来,还加上了一个“表头”。每次先选一列没找到‘1’的列,如果没有,则寻找失败;如果有,选择一行,把这行,这行有‘1’的列,与这行有公共列出现
Flotherm XT学习历程
大家好,通过半年的热仿真软件学习使用,最终发现最好用,最好上手的软件就是Flotherm XT,对新手非常友好,但由于软件近几年才发布,网上教程非常少,后面我将在这里持续分析软件使用心得,和大家一起学习。
从HSPICE到Spectre:手把手教你搞定不同SPICE仿真器的网表转换(附避坑指南)
本文详细介绍了从HSPICE到Spectre的SPICE仿真器网表转换方法,包括核心语法差异、分步转换流程和常见问题排查。通过实战案例和避坑指南,帮助工程师高效解决不同SPICE仿真器间的兼容性问题,提升集成电路设计效率。
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
知识图谱构建中的数据清洗:AI原生应用高质量图谱的前提
数据清洗是知识图谱构建的核心前置环节,直接决定AI原生应用(如智能问答、个性化推荐、决策支持系统)的图谱质量与应用效能。本文以第一性原理为起点,系统解析数据清洗的理论框架、技术架构与工程实践,覆盖从多源异构数据的噪声检测到高质量知识三元组(实体-关系-实体)生成的全流程。通过层次化概念映射(专家→中级→入门)、数学形式化建模及工业级案例分析,揭示数据清洗在解决实体歧义、关系冲突、结构不一致等关键问题中的技术逻辑,并展望基于大模型的智能清洗范式演化。Completeness(完整性)
POJ 3740 Easy Finding(精确覆盖模板题)
题目大意 给定一个M*N的01矩阵,能否找到一个行的集合,使得集合中每一列都恰好包含一个1。
让 ABAP 再次优雅:全面认知 ABAP Development Tools for SAP HANA(ADT)与可运行示例
本文介绍了ABAP开发工具ADT(ABAP Development Tools for SAP HANA)的核心概念与价值。ADT是基于Eclipse的现代化ABAP集成开发环境,支持ABAP Platform、S/4HANA等后端开发,提供代码编辑、CDS数据建模、质量检查等全流程功能,相比传统SAP GUI具有显著优势。文章详细阐述了ADT与SAP HANA的关系、关键能力模块(如代码重构、CDS建模、质量管控等),并通过一个制造企业案例说明其实际应用场景。最后提供了ADT安装指南和一个完整的ABAP
Open3D 球旋转算法(BPA)三维建模【2026最新版】
球旋转算法,博客长期更新,本文最新更新时间为:2026年4月11日。
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 =
互联网人提高效率必备软件合集
很多的时候我们解决不了问题,只是因为没有找到对的工具,实际上,很多好的工具就在那里,只是你不用而已。这点上,信息壁垒是一个很大的原因,因此我希望兄伙伴们多出去走走,不要只是局限在一个圈层;
[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
TMS_WebGMaps_1.9.8.0_Full_Source
TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder
廖雪峰Python教程[完整版]
廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白
[poj3740]Easy Finding_状态压缩_dfs
Easy Finding poj-3470 题目大意:给你一个01矩阵,问能否选出一些行,使得这些行所新组成的01矩阵每列中有且只有1个1。 注释:1<=行数<=16,1<=列数<=300. 想法:对于一个单独的01矩阵来讲,我们可以用一个数表示其中的每一行,然后暴力枚举每一行选取情况即可。 最后,附上丑陋的代码... ... ...
大中型超市收银系统(可直接运行)
光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开
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
482



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



