zoukankan      html  css  js  c++  java
  • [luogu 1092] 虫食算 (暴力搜索剪枝)

    传送门

    Description

    Input

    包含四行。
    第一行有一个正整数 (N≤26)。

    后面的三行,每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这3个字符串左右两端都没有空格,从高位到低位,并且恰好有N位。

    Output

    一行,即唯一的那组解。

    解是这样表示的:输出NN个数字,分别表示A,B,C,…所代表的数字,相邻的两个数字用一个空格隔开,不能有多余的空格。

    Sample Input

    5
    ABCED
    BDACE
    EBBAA

    Sample Output

    1 0 3 4 2

    INIT

    对于30%的数据,保证有N≤10;

    对于50%的数据,保证有N≤15;

    对于全部的数据,保证有N≤26。

    noip2004提高组第4题

    Solution

    暴力搜索剪枝没啥好说的。。。
    写完才明白按照一列搜索比按字母搜索要快好多,也好剪枝
    于是我写了一大堆特判才卡过

    Code

    丑陋的代码

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define F(i,a,b) for(register int i=(a);i<=(b);i++)
    #define R(i,a,b) for(register int i=(b);i>=(a);i--)
    using namespace std;
    
    inline int read() {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    
    const int N=30;
    bool flag;
    int n,tot,cnt;
    bool vis[N];
    int A[N],B[N],C[N],mp[N],sta[N],deg[N],id[N];
    char ch[N];
    
    bool ck() {
    	int A1=mp[A[1]],B1=mp[B[1]],C1=mp[C[1]];
    	if(~A1&&~C1&&A1>C1) return 0;
    	if(~B1&&~C1&&B1>C1) return 0;
    	if(~A1&&~B1) {
    		if(A1+B1>tot-1) return 0;
    		if(~C1&&A1+B1!=C1&&A1+B1+1!=C1) return 0;
    	}
    	int las=0;
    	R(i,1,n) {
    		int CA=A[i],CB=B[i],CC=C[i];
    		int &DA=mp[A[i]],&DB=mp[B[i]],&DC=mp[C[i]];
    		if(~DA&&~DB&&~DC) {
    			if(las==-1&&(DA+DB+1)%tot!=DC&&(DA+DB)%tot!=DC) return 0;
    			if(~las&&(DA+DB+las)%tot!=DC) return 0;
    			if(~las) las=(DA+DB+las)/n;
    			if(las==-1&&DA+DB>=n) las=1;
    		}
    		else if(~DA&&~DB) {
    			if(~las&&vis[(DA+DB+las)%tot]) return 0;
    			if(las==-1&&vis[(DA+DB)%tot]&&vis[(DA+DB+1)%tot]) return 0;
    			if(~las&&DC==-1) DC=(DA+DB+las)%tot,vis[DC]=1,sta[++cnt]=CC;
    		}
    		else if(~DA&&~DC) {
    			int dc=DC; if(dc<=DA) dc+=tot;
    			if(~las&&vis[dc-DA-las]) return 0;
    			if(las==-1&&vis[dc-DA]&&vis[dc-DA-1]) return 0;
    			if(~las&&DB==-1) DB=dc-DA-las,vis[DB]=1,sta[++cnt]=CB;
    		}
    		else if(~DB&&~DC) {
    			int dc=DC; if(dc<=DB) dc+=tot;
    			if(~las&&vis[dc-DB-las]) return 0;
    			if(las==-1&&vis[dc-DB]&&vis[dc-DB-1]) return 0;
    			if(~las&&DA==-1) DA=dc-DB-las,vis[DA]=1,sta[++cnt]=CA;
    		}
    		if(~DA&&~DB&&~las) las=(DA+DB+las)/n;
    		if(las==-1&&~DA&&~DB&&DA+DB>=n) las=1;
    		if(DA==-1||DB==-1||DC==-1) las=-1;
    	}
    	return 1;
    }
    
    void dfs(int pos) {
    	if(flag) return ;
    	if(~mp[id[pos]]) {dfs(pos+1);return ;}
    	if(pos==tot+1) {
    		F(i,1,tot) printf("%d ",mp[i]);
    		flag=1; return ;
    	}
    	F(i,0,tot-1) if(!vis[i]) {
    		mp[id[pos]]=i; vis[i]=1; int ls=cnt;
    		if(ck()) dfs(pos+1);
    		mp[id[pos]]=-1; vis[i]=0; 
    		while(cnt>ls) vis[mp[sta[cnt]]]=0,mp[sta[cnt]]=-1,cnt--;
    		if(flag) return ;
    	}
    }
    
    bool cmp(int x,int y) {return deg[x]>deg[y];}
    
    int main() {
    	n=read();
    	scanf("%s",ch+1);F(i,1,n) {A[i]=ch[i]-'A'+1;if(!vis[A[i]]) tot++,vis[A[i]]=1;deg[A[i]]++;}
    	scanf("%s",ch+1);F(i,1,n) {B[i]=ch[i]-'A'+1;if(!vis[B[i]]) tot++,vis[B[i]]=1;deg[A[i]]++;}
    	scanf("%s",ch+1);F(i,1,n) {C[i]=ch[i]-'A'+1;if(!vis[C[i]]) tot++,vis[C[i]]=1;deg[A[i]]++;}
    	memset(mp,-1,sizeof(mp)); memset(vis,0,sizeof(vis));
    	F(i,1,n) id[i]=i;
    	sort(id+1,id+1+n,cmp);
    	F(i,1,n) if(A[i]==B[i]&&B[i]==C[i]) {mp[A[i]]=0;vis[0]=1;dfs(1);return 0;}
    	F(i,1,n) if((A[i]==C[i])&&A[i]!=B[i]) {
    		mp[B[i]]=0;vis[0]=1;dfs(1);mp[B[i]]=-1;vis[0]=0;
    		if(!flag) {mp[A[i]]=0;vis[0]=1;mp[B[i]]=tot-1;vis[tot-1]=1;dfs(1);}
    		return 0;
    	}
    	F(i,1,n) if((B[i]==C[i])&&A[i]!=B[i]) {
    		mp[A[i]]=0;vis[0]=1;dfs(1);mp[A[i]]=-1;vis[0]=0;
    		if(!flag) {mp[B[i]]=0;vis[0]=1;mp[A[i]]=tot-1;vis[tot-1]=1;dfs(1);}
    		return 0;
    	}
    	dfs(1);
    	return 0;
    }
    
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    正则表达式
    前端开发工程师
    前端开发工程师
    Java开发工程师(Web方向)
    Java开发工程师(Web方向)
    Java开发工程师(Web方向)
    Java开发工程师(Web方向)
    Java开发工程师(Web方向)
    前端开发工程师
    前端开发工程师
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9732878.html
Copyright © 2011-2022 走看看