传送门:D. Monopole Magnets

这一场也是很神奇了,先是推迟三天,后是评测鸡崩了,unrated...

题意:每一行,每一列必须都要至少有一个s,n要可以到所有的黑格,n的上下左右如果有一个s,他就可以往那个方向移动一格,n最后不能在白格,求n最少的个数。

题解:

1、每一行每一列如果有#,#必须是连续的,否则输出-1

2、如果有一行没有#,那么至少有一列要没有#,s就可以放在交点处,否则输出-1。

3、求解连通块的个数

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 char a[1010][1010];
 6 bool x[1010],y[1010];       //x记录有#的行,y记录有#的列
 7 int dx[]={1,-1,0,0};
 8 int dy[]={0,0,1,-1};
 9 
10 void dfs(int xx,int yy)
11 {
12     a[xx][yy]='.';
13     for(int i=0;i<4;i++){
14         int xxx=xx+dx[i];
15         int yyy=yy+dy[i];
16         if(a[xxx][yyy]=='#') dfs(xxx,yyy);
17     }
18     return ;
19 }
20 
21 int main()
22 {
23     ios::sync_with_stdio(false);
24     cin.tie(0);
25     cout.tie(0);
26     int n,m;
27     cin>>n>>m;
28     for(int i=0;i<n;i++) cin>>a[i];
29     int flag=1;
30     for(int i=0;i<n;i++){
31         for(int j=0;j<m;j++){
32             if(a[i][j]=='#') {
33                 if(x[i]&&j&&a[i][j-1]!='#'){
34                     flag=0;
35                     break;
36                 }
37                 if(y[j]&&i&&a[i-1][j]!='#'){
38                     flag=0;
39                     break;
40                 }
41                 x[i]=1,y[j]=1;
42             }
43         }
44         if(!flag) break;
45     }
46     int p=0,q=0;
47     for(int i=0;i<n;i++) if(!x[i]) p=1;
48     for(int i=0;i<m;i++) if(!y[i]) q=1;
49     if(p^q) flag=0;     //如果有行没有# 而没有列没有#或者反过来,就输出-1.
50     if(!flag) {cout<<-1<<endl;return 0;}
51     int ans=0;
52     for(int i=0;i<n;i++){
53         for(int j=0;j<m;j++){
54             if(a[i][j]=='#') ans++,dfs(i,j);    //简单的找连通块
55         }
56     }
57     cout<<ans<<endl;
58     return 0;
59 }