[ZJOI2007]矩阵游戏【bzoj1059/洛谷1129】/ [HEOI2016/TJOI2016]游戏
小QQ是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏。矩阵游戏在一个N \times NN×N黑白方阵进行(如同国际象棋一般,只是颜色是随意的)。每次可以对该矩阵进行两种操作:
行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)
列交换操作:选择矩阵的任意两列,交换这两列(即交换对应格子的颜色)
游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。
对于某些关卡,小QQ百思不得其解,以致他开始怀疑这些关卡是不是根本就是无解的!于是小QQ决定写一个程序来判断这些关卡是否有解。
目标状态要求矩阵的主对角线上的格子均为黑色。
即是(1,1),(2,2),(3,3)......(n,n)皆匹配;
如果原图满足每行和每列都匹配,那么通过交换,一定可以换成上面这种情况。
所以拆行和列跑一个最大二分图匹配,并判断匹配数是否等于n即可。
代码见
#include<bits/stdc++.h>
#define re register int
#define maxn 200+5
using namespace std;
int t,n;
int ma[maxn][maxn];
inline int read(){
int x=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-;
ch=getchar();
}
while(isdigit(ch)){
x=(x<<)+(x<<)+ch-'';
ch=getchar();
}
return x*f;
}
int ans,match[maxn];
bool ed[maxn][maxn],vis[maxn];
bool dfs(int x){
for(re i=;i<=n;i++)
if(!vis[i]&&ed[x][i]){
vis[i]=true;
if(!match[i]||dfs(match[i]))
{
match[i]=x;
return true;
}
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
t=read();
while(t--)
{
ans=;
memset(match,,sizeof(match));
memset(ed,false,sizeof(ed));
n=read();
for(re i=;i<=n;i++)
for(re j=;j<=n;j++)
ed[i][j]=read();
for(re i=;i<=n;i++)
{
memset(vis,false,sizeof(vis));
ans+=dfs(i);
}
if(ans==n) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return ; }
[HEOI2016/TJOI2016]游戏
在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂。简单的说,这个游戏就是在一张地图上放上若干个炸弹,看是否能炸到对手,或者躲开对手的炸弹。在玩游戏的过程中,小H想到了这样一个问题:当给定一张地图,在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到。炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威力可以穿透软石头,但是不能穿透硬石头。给定一张n*m的网格地图:其中*代表空地,炸弹的威力可以穿透,可以在空地上放置一枚炸弹。x代表软石头,炸弹的威力可以穿透,不能在此放置炸弹。#代表硬石头,炸弹的威力是不能穿透的,不能在此放置炸弹。例如:给出1*4的网格地图*xx*,这个地图上最多只能放置一个炸弹。给出另一个1*4的网格地图*x#*,这个地图最多能放置两个炸弹。现在小H任意给出一张n*m的网格地图,问你最多能放置多少炸弹。
显然 这道题和上面的题极为相像。
需要处理的是把联通的序列(包括空地和软石头)行和列分别处理,进行二分图匹配。
#include<bits/stdc++.h>
#define re register int
#define maxn 50+5
#define maxn1 2500+5
using namespace std;
int n,m;
int cnt,tot;
char ma[maxn][maxn];
int row[maxn][maxn],col[maxn][maxn];
struct edge{
int nex,to;
}ed[maxn1];
int head[maxn1];
inline int read(){
int x=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-;
ch=getchar();
}
while(isdigit(ch)){
x=(x<<)+(x<<)+ch-'';
ch=getchar();
}
return x*f;
}
inline void write(int x){
if(x<){
putchar('-');
x=-x;
}
if(x>) write(x/);
putchar(x%+'');
}
int ans,match[maxn1];
bool vis[maxn1];
bool dfs(int x){
for(re e=head[x],v;e;e=ed[e].nex)
{
if(!vis[v=ed[e].to])
{
vis[v]=true;
if(!match[v]||dfs(match[v]))
{
match[v]=x;
return true;
}
}
}
return false;
}
void add(int x,int y) {
ed[++cnt].nex=head[x];
ed[cnt].to=y;
head[x]=cnt;
}
char get(){
char ch;
while((ch=getchar())!='#'&&ch!='*'&&ch!='x');
return ch;
}
int main()
{
ios::sync_with_stdio(false);
n=read();
m=read(); ;
for(re i=;i<=n;i++)
for(re j=;j<=m;j++)
ma[i][j]=get();
for(re i=;i<=n;i++)
for(re j=;j<=m;j++){
if(ma[i][j]=='#') continue;
if(j==||ma[i][j-]=='#') tot++;
row[i][j]=tot;
}
for(re i=;i<=m;i++)
for(re j=;j<=n;j++){
if(ma[j][i]=='#') continue;
if(j==||ma[j-][i]=='#') tot++;
col[j][i]=tot;
}
for(re i=;i<=n;i++)
for(re j=;j<=m;j++)
{
if(ma[i][j]!='*') continue;
add(row[i][j],col[i][j]);
}
for(re i=;i<=tot;i++)
{
memset(vis,false,sizeof(vis));
ans+=dfs(i);
}
write(ans);
return ; }
[ZJOI2007]矩阵游戏【bzoj1059/洛谷1129】/ [HEOI2016/TJOI2016]游戏的更多相关文章
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP
洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...
- BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...
- 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告
P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告
P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...
- 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告
P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...
- 洛谷P4093 [HEOI2016/TJOI2016]序列
题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一个值发生变化.现在佳媛姐姐已经研究出了所有变化的可能性, ...
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- [洛谷P4091][HEOI2016/TJOI2016]求和
题目大意:给你$n(n\leqslant10^5)$,求:$$\sum\limits_{i=0}^n\sum\limits_{j=0}^i\begin{Bmatrix}i\\j\end{Bmatrix ...
- [洛谷P4092][HEOI2016/TJOI2016]树
题目大意:给你一棵树,有两个操作: $C\;x:$给第$x$个节点打上标记 $Q\;x:$询问第$x$个节点的祖先中最近的打过标记的点(自己也是自己的祖先) 题解:树剖,可以维护区间或,然后若一段区间 ...
随机推荐
- 使用eclipse新建一个c项目
一.打开eclipse并新建项目 1.快捷键:字体放大:Ctrl+Shift+“+” 字体缩小:Ctrl+“-”
- POJ - 3264——Balanced Lineup(入门线段树)
Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 68466 Accepted: 31752 ...
- flex布局-弹性布局
弹性布局当前应用的非常广泛,特别是移动端,记得第一次用reactNative 写代码的时候是最开始真正接触Flex布局.1.首先最外层的容器需要指定为display:flex;由于flex的兼容版本还 ...
- websocket session共享
单机运行 用户a通过服务器进入房间room,用户b也通过房间进入room,用户之间是通过session来通话的,所以session直接存储在集合中就可以了. 因为session存储在一台服务器的集合中 ...
- python入门(三)
一.判断(精简代码) 非空为真,非0为真# 不为空的话就是true,是空的话就是false# 只要不是0就是true,是0就是falsea=[]#list也是假的b={}#字典也是假的c=0 #也是假 ...
- 20190219备份 java spring boot 学习链接(日/英)
Building web applications with Spring Boot and Kotlin https://www.slideshare.net/masuda220/spring-82 ...
- 比较爬虫用的语言Python与Go
Python是我比较喜欢的语言,莫名的喜欢,对Python的学习可能起初是敲错了网址开始的,哈哈哈~ 工作的任务从一个网站后台做登录.爬取数据,写入服务器Redis中,同事认为我会用PHP来写,哼!让 ...
- c#@三种作用
以前只知道@在C#中为了写文件路径的\不要加转义符而在前面加上@标识符,没想到@还有其他的作用 1.忽略转义字符例如string fileName = "D:\\文本文件\\text.txt ...
- servlet操作本地文件汇总: 判断文件是否存在;文件重命名;文件复制; 获取文件属性信息,转成Json对象; 获取指定类型的文件; 查找替换.txt中的文本
package servlet; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; ...
- 20165214 2018-2019-2 《网络对抗技术》Exp2 后门原理与实践 Week4
<网络对抗技术>Exp2 PC平台逆向破解之"MAL_简单后门" Week4 一.实验内容 本次实验对象为名为pwn1的pwn1的linux可执行文件.程序正常执行流程 ...