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;
    } 
    

      

  • 相关阅读:
    45套精美的 ( Android, iPhone, iPad ) 手机界面设计素材和线框图设计工具
    JAVA基础01
    这是我的第一个博客
    string(更新)
    KMP
    标准C++中的string类的用法总结
    coj 数学作业(300)
    异或的性质及运用
    substr在oracle和mysql中的应用和区别
    非空校验在oracle和mysql中的用法
  • 原文地址:https://www.cnblogs.com/Ean1zhi/p/12953521.html
Copyright © 2011-2022 走看看