博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【魔板】题解
阅读量:4353 次
发布时间:2019-06-07

本文共 2686 字,大约阅读时间需要 8 分钟。

大家好,我是学习竞赛一年半的超级小周,喜欢唱,跳,rap,篮球。下面我将为大家分析这题为什么只能用搜索+枚举(为什么我没做出来...

首先,我们把搜索和枚举在脑海里划掉,这时我们会想到哪种方法?由于只能交换任意两列数字(对一行的数字来说只是交换两个数字)或把每行数字 00 变成 11 , 11 变成 00 (有规律的改变 00 , 11 个数),很容易想到用一个数组记录每一行 11 的个数(可以表示为每一行数字的和),将两个魔板每一行进行比较。如果发现两个魔板有一行的 11 的个数失配(就是 ii != jj && ii != mm - jj )就可以输出NO了。另外,在匹配过程中,如果匹配失败,我们会非常高兴的把那行数字 00 变成 11 , 11 变成 00 。这样,匹配完成之时,我们就可以任意去交换两列的位置,用暴力枚举来判断是否可以让两魔板匹配,由于只有 00 , 11 ,我们很容易想到用map来辅助我们判断,我们甚至可以用哈希表( 00 , 11 想到了什么?二进制啊!)来节约时间。这样看来,我们离AC不远了...

真的不远了吗?错!认为能A的都是cxk,如果出现 00 的个数= 11 的个数,那我们就无法判断那行该不该转换了,那行就会出现两种情况。所以,愣着干啥啊,只能枚举啦!

枚举的代码:

#include
#include
#include
#include
using namespace std;int K,n,m, a[110][110],h[110],l[110];int o[110][110];bool juge[110],yes,pm;int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar(); return x*f;}bool cmp(int x,int y){ for(int i=1;i<=n;++i) if(o[i][x]!=a[i][y])return false; return true;}void dfs(int p){ if(p>m){yes=false;return;}//如果一直都没找到,就返回啦 for(int i=1;yes&&i<=m;++i) if(!juge[i]&&cmp(p,i)) { juge[i]=true; dfs(p+1);//搜索+回溯 juge[i]=false; }}int main(){ K=read(); while(--K>=0) { yes=true; memset(h,0,sizeof(h)); memset(l,0,sizeof(l)); n=read(); m=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) a[i][j]=read(),h[i]+=a[i][j];//记录1的个数 for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) o[i][j]=read(),l[i]+=o[i][j];//记录1的个数 for(int i=1;yes&&i<=m;++i) { pm=true; for(int j=1;pm&&j<=n;++j) { if(a[j][i]!=o[j][1])//反 { for(int k=1;k<=m;++k)a[j][k]=a[j][k]^1;//^效率高 h[j]=m-h[j]; } if(h[j]!=l[j])pm=false;//这里是判断上面说的i==j||i==m-j } if(!pm)continue; juge[i]=true; dfs(2);//开始搜 juge[i]=false; } if(yes)printf("NO\n"); else printf("YES\n"); } return 0;}

咦?怎么A了?数据这么水?

这题毒瘤的地方就在这,如果每行都有两种情况,那时间就会大大增加,这时打得不好的暴力枚举就差不多超时了(可我还是没超,我同学超了,详见讨论帖),那怎么办?...没看前面啊?用哈希表或map来辅助判断啊!

map格式

map
www;string s;s+='0'或'1';...一列存完后。。。www[s]=1;查找...每次用完记得清空

哈希是我大胆提出的一个思路,因为只有01很容易想到2进制,显然不会冲突

由于数据2的100次方超出限制,我们可以以四个长度>=25的数组分别求哈希值,再判断。步骤与map相似。

这题主要考察的是简单的搜索和要想办法优化的匹配。当然,这题真的可以不用枚举去过(这就要用数学相关的知识),超级小周学识浅薄,就算知道也不能很好的解释出来。所以就给读者留下一些想象空间吧!

以后我还会多发题解,喜欢的话就多多支持我吧!mua!(逃)

转载于:https://www.cnblogs.com/yanzifanqiejiang/p/11552267.html

你可能感兴趣的文章
BZOJ 3527: [Zjoi2014]力 [快速傅里叶变换]
查看>>
LeetCode Palindrome Permutation II
查看>>
LeetCode Minimum Index Sum of Two Lists
查看>>
linux学习系列三
查看>>
细看Thread的 start() 和 run()方法
查看>>
Maven项目无法添加到tomcat
查看>>
查看公司工商注册信息
查看>>
小tip: 使用SVG寥寥数行实现圆环loading进度效果
查看>>
科技发展潮流
查看>>
Reactor-反应器模式
查看>>
Object的wait/notify/notifyAll&&Thread的sleep/yield/join/holdsLock
查看>>
MVC3+EntityFramework实践笔记
查看>>
一个漂亮的 PlaceHolder
查看>>
jq 中.html(),.text()和.val()的总结
查看>>
ACE OLEDB 12.0连接方式
查看>>
Stack,( Aizu - ALDS1_3_A)
查看>>
javascript_17-基本类型和引用类型
查看>>
django paginator 分页功能
查看>>
java arrayList vector 区别
查看>>
测试思想-文档评审 关于需求评审
查看>>