zoukankan      html  css  js  c++  java
  • P1092 虫食算 题解(搜索)

    题目链接

    P1092 虫食算

    解题思路

    好题啊!这个搜索好难写......

    大概是要考虑进位和考虑使用过某个数字这两个东西,但就很容易出错......

    首先这个从后往前搜比较好想,按照从后往前出现的顺序搜,在这个剪枝条件下速度会快很多。

    比如样例,

    5
    ABCED
    BDACE
    EBBAA

    从右往左出现的次序是(DEAECACABBDBABE),去重之后是(DEACB),这就是要搜索的顺序,用(seq)记录。

    当某时候等式明显已经不满足时,就直接(return)

    还有别的剪枝,但这样直接能(79ms)。没必要。

    AC代码

    #include<stdio.h>
    #include<stdlib.h>
    #define N 30
    int n,a[N],b[N],c[N],vis[N],ans[N];
    char s[3][N];
    int seq[N];//搜索顺序 
    void dfs(int x){//搜到第x个元素 
    	int i,jw=0;
    	if(ans[a[0]]+ans[b[0]]>=n)return;
    	for(i=n-1;i>=0;i--){//从后往前检查 
    		int A=ans[a[i]],B=ans[b[i]],C=ans[c[i]];
    		if(A==-1||B==-1||C==-1)continue;
    		if((A+B+1)%n!=C&&(A+B)%n!=C)return;
    	}
    	if(x==n){
    		for(i=n-1;i>=0;i--){
    			int A=ans[a[i]],B=ans[b[i]],C=ans[c[i]];
    			if((A+B+jw)%n!=C)return;
    			jw=(A+B+jw)/n;
    		}
    		for(i=0;i<n;i++)printf("%d ",ans[i]);
    		exit(0);
    	}
    	for(i=n-1;i>=0;i--){
    		if(!vis[i]){
    			vis[i]=1;ans[seq[x]]=i;
    			dfs(x+1);
    			vis[i]=0;ans[seq[x]]=-1;
    		}
    	}
    }
    int cnt;
    void f(int x){//提供搜索顺序,加快搜索速度 
    	if(!vis[x]){vis[x]=1;seq[cnt++]=x;}
    }
    int main(){
    	int i;
    	for(i=0;i<30;i++)ans[i]=-1;
    	scanf("%d%s%s%s",&n,s[0],s[1],s[2]);
    	for(i=0;i<n;i++){
    		a[i]=s[0][i]-'A';
    		b[i]=s[1][i]-'A';
    		c[i]=s[2][i]-'A';
    	}
    	for(i=n-1;i>=0;i--){f(a[i]);f(b[i]);f(c[i]);}
    	for(i=0;i<n;i++)vis[i]=0;
    	dfs(0);
    	return 0;
    }
    

    这是seq优化后的结果:

    这是从n-1到1搜索的结果:

    而这是从1到n-1搜索的结果:

  • 相关阅读:
    prepareStatement的用法和解释
    java socket报文通信(一) socket的建立
    java多线程小结
    Java_XML操作
    socket实例2
    socket实例1
    Socket小结
    从源码角度理解android动画Interpolator类的使用
    android使用属性动画代替补间动画
    OKHttp的简单使用
  • 原文地址:https://www.cnblogs.com/Potassium/p/10462818.html
Copyright © 2011-2022 走看看