zoukankan      html  css  js  c++  java
  • cf_936D

    这道题,属实将我搞懵了,看了好久才将题意看懂。

    刚开始因为认为除了特判情况下,每一行每一列都要存在#,然后当#之间存在’  .  ‘时便直接为-1.

    后来发现存在情况,当行和列都存在空行时也符合条件。

    最基本例子:

     当第一行和最后一列都为.,反而能在(1,n)处放N极,且不影响,因此只要将这个条件判过,这道题就能过了。

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int N=2e5;
    int mp[1005][1005];
    vector<int> rs[1005],cc[1005];
    int r[1005],c[1005];
    int vis[1005][1005];
    struct node{
    	int x,y;
    };
    int n,m;
    int bfs(int x,int y){
    	node s;
    	int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    	s.x=x,s.y=y;
    	vis[x][y]=1;
    	queue<node> sk;
    	sk.push(s);
    	while(!sk.empty()){
    		node k=sk.front();
    		sk.pop();
    		int nx=k.x,ny=k.y;
    		for(int i=0;i<4;i++){
    			int dx=nx+dir[i][0];
    			int dy=ny+dir[i][1];
    			if(!vis[dx][dy]&&mp[dx][dy]==0&&(dx>=1&&dx<=n&&dy>=1&&dy<=m)){
    				vis[dx][dy]=1;
    				sk.push(node{dx,dy});
    			}
    		}
    	}
    	return 1;
    }
    int main(){
    	cin>>n>>m;
    	int op=0;
    	int sum=0;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			char a;cin>>a;
    			if(a=='.'){
    				mp[i][j]=1;
    				vis[i][j]=1;
    			}
    			else{
    				op++;
    				rs[i].push_back(j);
    				cc[j].push_back(i);
    				r[i]++;
    				c[j]++;
    			}
    		}
    	}
    	if(op==0){
    		cout<<0<<endl;
    		return 0;
    	}
    	int fx=0,fy=0;
    	for(int i=1;i<=n;i++){//判断空行
    		if(r[i]==0){
    			fx=1;
    		}
    	}
    	for(int j=1;j<=m;j++){//空列
    		if(c[j]==0){
    			fy=1;
    		}
    	}
    	if(fx^fy){//当都存在空行或都不存在时可继续,反正输出-1
    		cout<<-1<<endl;
    		return 0;
    	}
    	for(int i=1;i<=n;i++){//判断#之间是否存在‘。’
    		if(rs[i].size()>=2){
    			for(int j=1;j<rs[i].size();j++){
    				int s=rs[i][j]-rs[i][j-1];
    				if(s!=1){
    					cout<<-1<<endl;
    					return 0;
    				}
    			}
    		}
    	}
    	for(int i=1;i<=m;i++){//同上
    		if(cc[i].size()>=2){
    			for(int j=1;j<cc[i].size();j++){
    				int s=cc[i][j]-cc[i][j-1];
    				if(s!=1){
    					cout<<-1<<endl;
    					return 0;
    				}
    			}
    		}
    	}
    	for(int i=1;i<=n;i++){//计算连通块数量。
    		for(int j=1;j<=m;j++){
    			if(!vis[i][j]){
    				sum+=bfs(i,j);
    			}
    		}
    	}
    	cout<<sum<<endl;
    	return 0;
    } 
    

      

  • 相关阅读:
    ....
    CodeForces 375A(同余)
    POJ 2377 Bad Cowtractors (最小生成树)
    POJ 1258 AgriNet (最小生成树)
    HDU 1016 Prime Ring Problem(全排列)
    HDU 4460 Friend Chains(bfs)
    POJ 2236 Wireless Network(并查集)
    POJ 2100 Graveyard Design(尺取)
    POJ 2110 Mountain Walking(二分/bfs)
    CodeForces 1059B Forgery(模拟)
  • 原文地址:https://www.cnblogs.com/Ean1zhi/p/12953521.html
Copyright © 2011-2022 走看看