noi.ac NA536 打地鼠
Posted --bluesky007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noi.ac NA536 打地鼠相关的知识,希望对你有一定的参考价值。
又一道可写的小清新思维题
其实想到倒着做了,然而还是因为T1害人不浅(我太菜了),所以并没有写
考虑两个局面不同,显然至少打了一次地鼠,基于操作的颜色覆盖性质,我们可以考虑把操作倒着做,对于一个X
点,其同行同列没有其他的X
点,则可以考虑将该点逆操作,其同行同列的原颜色可以不被考虑,对于一个颜色忽略不计的点,如果其同行同列没有X
点,则亦可忽略其同行同列的颜色,对此可以BFS解决,时间复杂度\(\mathcalO(nm)\)
#include<bits/stdc++.h>
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N=1010;
int n,m,a[N][N],b[N][N];
char s[N][N],t[N][N];
queue<pii>q;
bool checks()
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]!='X')
return 0;
return 1;
bool checkt()
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(t[i][j]!='O')
return 0;
return 1;
int cntrow[N],cntcol[N];
bool vis[N][N],viscol[N],visrow[N];
void bfs(int u,int v)
if(!viscol[v])
viscol[v]=1;
for(int i=1;i<=n;i++)
if(i==u)
continue;
b[i][v]=-1;
if(!cntrow[i])
q.push(mk(i,v));
if(!visrow[u])
visrow[u]=1;
for(int i=1;i<=m;i++)
if(i==v)
continue;
b[u][i]=-1;
if(!cntcol[i])
q.push(mk(u,i));
bool solve()
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!b[i][j]&&cntrow[i]==1&&cntcol[j]==1)
q.push(mk(i,j));
b[i][j]=-1;
vis[i][j]=1;
while(!q.empty())
pii pr=q.front();q.pop();
bfs(pr.fi,pr.se);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(~b[i][j])
if(a[i][j]^b[i][j])
return 0;
return 1;
int main()
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%s",s[i]+1);
for(int j=1;j<=m;j++)
a[i][j]=s[i][j]!='X';
for(int i=1;i<=n;i++)
scanf("%s",t[i]+1);
for(int j=1;j<=m;j++)
b[i][j]=t[i][j]!='X';
cntrow[i]+=!b[i][j];
cntcol[j]+=!b[i][j];
if(checks()||checkt())
printf("0\n");
return 0;
printf("%d\n",solve()?1:0);
return 0;
以上是关于noi.ac NA536 打地鼠的主要内容,如果未能解决你的问题,请参考以下文章