半天看不懂题意只能补。。。
题面
题意
给定一张黑白图,要求放置南北磁极,南磁极不可移动(每行每列至少要有一个南磁极)
每次可以激活一对在同行或同列的南北磁极,使得北磁极向南磁极移动一格
要求在所有可能的移动过程中,北磁极不能到达白块,且又可以到达所有黑块
问最少需要放置多少个北磁极,才能走遍图中所有黑块
如果无法放置,输出 -1
解题思路
①如果某行或者某列存在两段及以上黑色块组成的线段
例如:
因为每行或每列必定存在至少一个南磁极,所以肯定存在一个移动方式使得北磁极经过中间的那段白色块
所以这种情况出现时不符题意,输出 -1
由此可得,只有黑色块组成线段只存在一段时才符合题意
所以例如: ..###.. | ###.... | ....### 都可行
而样例 2 的第一列: #..# 不可行
②如果某列全空且没有行全空,或者某行全空且没有列全空
例如:
上图中第三列全空,但没有任何一行为空
又因为每列必须有至少一个南磁极
所以也一定存在一种移动方式能够让北磁极移动到这个全白的列上,不符题意
③如果存在某列全空,且存在某行全空
例如:
那么只要让南磁极放置在交叉点上,则不会影响分割出来的四个象限里的北磁极的移动
即:
如果存在多个交叉点,则在每个交叉点上都放置一个南磁极即可
例如:
综上我们可以得到:
- 每一行或者每一列至多存在一条由黑色块组成的线段
- 全白行与全白列,要么同时存在,要么同时不存在
于是我们就把北磁极的移动路线固定在了每个黑色连通块之中
最后通过bfs或者dfs求出连通块数量即可
代码实现
在判断黑色块线段数量时,引入变量kd,初始值为0
循环某行或者某列
如果碰到了 '#' 且 kd 是 0 则变成 1 ,是 2 则直接输出 -1 并结束程序
如果碰到了 '.' 且 kd 是 1 则变成 2
所以最后如果kd==0,说明整行全是白色块
如果kd==1,说明这一行只有一段黑色块,且最后一个位置为黑色块
如果kd==2,说明这一行只有一段黑色块,且最后一个位置为白色块
否则就是直接输出 -1 的情况,说明由两段黑色块线段
完整程序
(46ms/2000ms)
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
char mp[1050][1050];
int n,m,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
inline bool prim(int x,int y)
{
return x>0&&y>0&&x<=n&&y<=m;
}
void bfs(int x,int y)
{
mp[x][y]='.';
queue<P> q;
q.push(P(x,y));
while(!q.empty())
{
P pd=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int px=pd.first+dx[i],py=pd.second+dy[i];
if(prim(px,py)&&mp[px][py]=='#')
{
mp[px][py]='.'; //把访问到的黑色块直接变成其他值即可
q.push(P(px,py));
}
}
}
}
void solve()
{
cin>>n>>m;
bool emptyRow=false,emptyColumn=false;
for(int i=1;i<=n;i++)
{
cin>>(mp[i]+1);
int kd=0;
for(int j=1;j<=m;j++) //遍历行
{
if(mp[i][j]=='.')
{
if(kd==1)
kd=2;
}
else
{
if(kd==0)
kd=1;
else if(kd==2)
{
cout<<"-1
";
return;
}
}
}
if(kd==0)
emptyColumn=true; //说明这行全是白色块
}
for(int j=1;j<=m;j++)
{
int kd=0;
for(int i=1;i<=n;i++)//遍历列
{
if(mp[i][j]=='.')
{
if(kd==1)
kd=2;
}
else
{
if(kd==0)
kd=1;
else if(kd==2)
{
cout<<"-1
";
return;
}
}
}
if(kd==0)
emptyRow=true; //说明这列全是白色块
}
if(emptyColumn!=emptyRow) //如果行全白且没有列全白,或者列全白且没有行全白
{
cout<<"-1
";
return;
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) //遍历整张图
if(mp[i][j]=='#') //如果存在没有访问到的黑色块
{
bfs(i,j);
ans++;
}
cout<<ans<<'
';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
solve();
return 0;
}