zoukankan      html  css  js  c++  java
  • [NOIP2004提高组]虫食算

    题目:洛谷P1092、codevs1064、Vijos P1099。

    题目大意:
    给你一个$n$进制、每个数都是$n$位的三个数a,b,c,这些数的数位由字母表示(共$n$个字母,从‘A’开始),所有数字都只对应一个字母,每个字母对应一个数字。
    现在知道a+b=c,求每个字母代表的数字,保证有且仅有一组解。
    解题思路:
    暴力,从后往前搜索每一列即可。注意传递进位。
    若一列知道了三个数,则判断是否合法,合法则继续搜索下一列。
    若一列知道了两个数,则可以推算出第三个数,若没被使用,则继续搜索下一列。
    若一列知道的数少于一个,则a或b中,一定有一个数字是不知道的。我们从大到小枚举那个数的值,然后搜**当前列**(递归)。
    如果发现答案可行,则直接输出答案,退出即可。
    这样搜,不用加其他剪枝,最大一个点最多800ms(其实上述分类讨论已经很好地进行了剪枝)。

    C++ Code:

    #include<bits/stdc++.h>
    int n,num[123],ur[123];
    char a[123],b[132],c[213];
    void dfs(int now,int jw){
    	if(now==-1){
    		for(int i=1;i<n;++i)printf("%d ",num[i+'A'-1]);
    		printf("%d
    ",num[n+'A'-1]);
    		exit(EXIT_SUCCESS);
    	}
    	int i=now;
    	//if(now!=n-1&&!check(now+1))return;
    	if(num[a[i]]!=-1&&num[b[i]]!=-1&&num[c[i]]!=-1){
    		int p=num[a[i]]+num[b[i]]+jw;
    		if(p%n==num[c[i]]){
    			dfs(now-1,p/n);
    		}
    		return;
    	}
    	if(num[a[i]]!=-1&&num[b[i]]!=-1){
    		int p=num[a[i]]+num[b[i]]+jw;
    		if(!ur[p%n]){
    			ur[p%n]=1;
    			num[c[i]]=p%n;
    			dfs(now-1,p/n);
    			num[c[i]]=-1;
    			ur[p%n]=0;
    		}
    		return;
    	}
    	if(num[a[i]]!=-1&&num[c[i]]!=-1){
    		int p=num[c[i]]-jw-num[a[i]]+n;
    		if(!ur[p%n]){
    			ur[p%n]=1;
    			num[b[i]]=p%n;
    			dfs(now-1,!(p/n));
    			num[b[i]]=-1;
    			ur[p%n]=0;
    		}
    		return;
    	}
    	if(num[b[i]]!=-1&&num[c[i]]!=-1){
    		int p=num[c[i]]-jw-num[b[i]]+n;
    		if(!ur[p%n]){
    			ur[p%n]=1;
    			num[a[i]]=p%n;
    			dfs(now-1,!(p/n));
    			num[a[i]]=-1;
    			ur[p%n]=0;
    		}
    		return;
    	}
    	if(num[a[i]]!=-1){
    		for(int j=n-1;j>-1;--j)
    		if(!ur[j]){
    			ur[j]=1;
    			num[b[i]]=j;
    			dfs(now,jw);
    			num[b[i]]=-1;
    			ur[j]=0;
    		}
    	}else{
    		for(int j=n-1;j>-1;--j)
    		if(!ur[j]){
    			ur[j]=1;
    			num[a[i]]=j;
    			dfs(now,jw);
    			num[a[i]]=-1;
    			ur[j]=0;
    		}
    	}
    }
    int main(){
    	scanf("%d%s%s%s",&n,a,b,c);
    	memset(ur,0,sizeof ur);
    	memset(num,-1,sizeof num);
    	dfs(n-1,0);
    	return EXIT_FAILURE;
    }
    
  • 相关阅读:
    那些年做过的外包 之 健康小屋
    Raize 重新编译
    解码淘口令?
    单品优惠券炸了
    如何共享联盟cookie
    阿里妈妈账号登录状态如何长时间保存
    delphi 图像旋转
    Canvas: Out of system resources
    关于&$地址传递的练习
    解决XAMPP中,MYSQL因修改my.ini后,无法启动的问题
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/9026478.html
Copyright © 2011-2022 走看看