zoukankan      html  css  js  c++  java
  • noi.ac NA536 【打地鼠】

    又一道可写的小清新思维题

    其实想到倒着做了,然而还是因为T1害人不浅(我太菜了),所以并没有写

    考虑两个局面不同,显然至少打了一次地鼠,基于操作的颜色覆盖性质,我们可以考虑把操作倒着做,对于一个X点,其同行同列没有其他的X点,则可以考虑将该点逆操作,其同行同列的原颜色可以不被考虑,对于一个颜色忽略不计的点,如果其同行同列没有X点,则亦可忽略其同行同列的颜色,对此可以BFS解决,时间复杂度(mathcal{O}(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
    ");
    		return 0;
    	}
    	printf("%d
    ",solve()?1:0);
    	return 0;
    }
    
  • 相关阅读:
    SICP习题 1.11 (一个函数的递归与迭代)
    SICP 实例 ExchangeMoney
    SICP 1.2.2 树形递归 与 线性迭代(斐波那契数)
    SICP习题 1.10(Ackermann函数)
    SICP习题 1.9 (递归与迭代初探)
    SICP实例 1.2.1 (阶乘的递归与迭代)
    SICP习题 1.8 (立方根)
    SICP习题 1.7 (求平方根改进)
    SICP习题 1.6 (再探 函数 与 正则序 应用序 关系)
    SICP实例 1.1.7 (求平方根)
  • 原文地址:https://www.cnblogs.com/--BLUESKY007/p/11144826.html
Copyright © 2011-2022 走看看