zoukankan      html  css  js  c++  java
  • BZOJ 4945 [Noi2017]游戏

    题解:

    这题怎么也卡常数(自己常数大)

    对于是x的位置令x='a'或'c' ('b')

    然后用2sat验证即可

    问题:缩点版的2sat还不会,貌似效率高

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=100009;
    
    int n,m,lim;
    int limt[maxn][3];
    char limc[maxn][3];
    
    int cntp=0;
    int xp[maxn];
    
    char ss[maxn];
    int cntedge=0;
    int head[maxn];
    int to[maxn<<1],nex[maxn<<1];
    void Addedge(int x,int y){
    	nex[++cntedge]=head[x];
    	to[cntedge]=y;
    	head[x]=cntedge;
    }
    
    int fla[maxn];
    int mark[maxn];
    char FS(int x){
    	if(ss[x]=='a')return 'b';
    	else return 'a';
    }
    char SE(int x){
    	if(ss[x]=='a')return 'c';
    	if(ss[x]=='b')return 'c';
    	if(ss[x]=='c')return 'b';
    }
    
    void Addlims(int i){
    	int t1=limt[i][1];
    	int t2=limt[i][2];
    	char c1=limc[i][1];
    	char c2=limc[i][2];
    	
    	if((t1==t2)&&(c1==c2))return;
    	if(c1==ss[t1])return;
    	if(c2==ss[t2]){
    		if(c1==FS(t1))fla[t1*2+1]=1;
    		else fla[t1*2]=1;
    		return;
    	}
    	int x,y;
    	if(c1==FS(t1))x=t1*2;
    	else x=t1*2+1;
    	if(c2==FS(t2))y=t2*2;
    	else y=t2*2+1;
    	Addedge(x,y);
    	Addedge(y^1,x^1);
    }
    
    int Sta[maxn],top;
    int Dfs(int x){
    	if(mark[x^1])return 0;
    	if(mark[x])return 1;
    	mark[x]=1;
    	Sta[++top]=x;
    	
    	for(int i=head[x];i;i=nex[i]){
    		if(!Dfs(to[i]))return 0;
    	}
    	return 1;
    }
    
    int Sol(){
    	cntedge=0;
    	memset(fla,0,sizeof(fla));
    	memset(head,0,sizeof(head));
    	memset(mark,0,sizeof(mark));
    	for(int i=1;i<=lim;++i)Addlims(i);
    //	for(int i=2;i<=n*2+1;++i)cout<<fla[i]<<' ';
    //	cout<<endl;
    	for(int i=2;i<=n*2+1;i+=2){
    		if((!fla[i])&&(!fla[i+1]))continue;
    		if(fla[i]&&fla[i+1])return 0;
    		if(fla[i]==1){
    			if(!Dfs(i))return 0;
    		}else{
    			if(!Dfs(i+1))return 0;
    		}
    	}
    //	for(int i=2;i<=n*2+1;++i)cout<<mark[i]<<' ';
    //	cout<<endl;
    	for(int i=2;i<=n*2+1;i+=2){
    		if((!mark[i])&&(!mark[i+1])){
    			top=0;
    			if(!Dfs(i)){
    				while(top){
    					mark[Sta[top]]=0;--top;
    				}
    				if(!Dfs(i+1))return 0;
    			}
    		}
    	}
    	for(int i=1;i<=n;++i){
    		if(mark[i*2]){
    			printf("%c",FS(i)-'a'+'A');
    		}else{
    			printf("%c",SE(i)-'a'+'A');
    		}
    	}
    	return 1;
    }
    
    int main(){
    //	freopen("game.in","r",stdin);
    //	freopen("game.out","w",stdout);
    	
    	scanf("%d%d",&n,&m);
    	scanf("%s",ss+1);
    	for(int i=1;i<=n;++i)if(ss[i]=='x')xp[++cntp]=i;
    	scanf("%d",&lim);
    	for(int i=1;i<=lim;++i){
    		scanf("%d",&limt[i][1]);
    		limc[i][1]=getchar();
    		while(limc[i][1]!='A'&&limc[i][1]!='B'&&limc[i][1]!='C')limc[i][1]=getchar();
    		limc[i][1]=limc[i][1]-'A'+'a';
    		scanf("%d",&limt[i][2]);
    		limc[i][2]=getchar();
    		while(limc[i][2]!='A'&&limc[i][2]!='B'&&limc[i][2]!='C')limc[i][2]=getchar();
    		limc[i][2]=limc[i][2]-'A'+'a';
    	}
    	for(int s=0;s<(1<<m);++s){
    		for(int i=1;i<=m;++i){
    			if(s&(1<<(i-1))){
    				ss[xp[i]]='c';
    			}else{
    				ss[xp[i]]='a';
    			}
    		}
    		if(Sol())return 0;
    	}
    	cout<<-1<<endl;
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    Jakarta雅加达项目简介
    java的Commons包简介
    装饰者模式
    命令模式
    桥接模式
    适配器模式
    观察者模式
    模板模式
    责任链模式
    CentOS搭建NAT和DHCP服务,实现共享上网
  • 原文地址:https://www.cnblogs.com/zzyer/p/8560819.html
Copyright © 2011-2022 走看看