codevs1064 虫食算

题目描述 Description

所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子:

43#9865#045
    +    8468#6633
       44445506978

其中#号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5。

现在,我们对问题做两个限制:

首先,我们只考虑加法的虫食算。这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0。


次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同的数字用不同的字母表示。如果这个算式是N进制的,我
们就取英文字母表午的前N个大写字母来表示这个算式中的0到N-1这N个不同的数字:但是这N个字母并不一定顺序地代表0到N-1)。输入数据保证N个字
母分别至少出现一次。

BADC
      +    CBDA
            DCCC

上面的算式是一个4进制的算式。很显然,我们只要让ABCD分别代表0123,便可以让这个式子成立了。你的任务是,对于给定的N进制加法算式,求出N个不同的字母分别代表的数字,使得该加法算式成立。输入数据保证有且仅有一组解,

输入描述
Input Description

输入包含4行。第一行有一个正整数N(N<=26),后面的3行每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这3个字符串左右两端都没有空格,从高位到低位,并且恰好有N位。

输出描述
Output Description

输出包含一行。在这一行中,应当包含唯一的那组解。解是这样表示的:输出N个数字,分别表示A,B,C……所代表的数字,相邻的两个数字用一个空格隔开,不能有多余的空格。

样例输入
Sample Input

5
ABCED
BDACE
EBBAA

样例输出
Sample Output

1 0 3 4 2

数据范围及提示
Data Size & Hint

对于30%的数据,保证有N<=10;
对于50%的数据,保证有N<=15;
对于全部的数据,保证有N<=26。

正解:搜索解题报告:

  今天考搜索专题的时候考了这道题,结果只有80分,一个T一个WA。

  仔细查了一下错,发现又犯低级错误了。首先我的下标从0开始那么我的搜索边界应该是-1,然而我只到了0,导致有个解没搜到。然后我打的只是裸搜索,没有一个很优秀的剪枝,就是每一步都check一下,还没搜到的等式是不是已经三个都出来了,如果已经都确定了,但是不管进不进位都无法做到的话,那就说明不合法,可以直接return。这样剪枝的话就跑得很快了,基本0.008s就可以过了。

  其余的就是裸搜索啦:

 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long LL;
15 #define RG register
16 const int MAXN = 27;
17 int n,ce,a[MAXN],b[MAXN],c[MAXN];
18 int match[MAXN],ans[MAXN];
19 char ch[MAXN];
20 bool ok,vis[MAXN];
21
22 inline int getint()
23 {
24        RG int w=0,q=0; RG char c=getchar();
25        while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar(); if(c==‘-‘) q=1,c=getchar();
26        while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar(); return q ? -w : w;
27 }
28
29 inline void dfs(RG int x,RG int type,RG int remain){
30     if(ok) return ;
31
32     RG int ans1,ans2,ans3;
33     for(int i=0;i<x;i++) {//进位最多是ce,如果某一位已经确定,但是进位不够则不合法
34     ans1=match[a[i]],ans2=match[b[i]],ans3=match[c[i]];
35     if(ans1==-1||ans2==-1||ans3==-1) continue;
36     if( ((ans3-ans2-ans1)%n+n)%n >ce) return ;
37     }
38
39     if(x==-1) {//!!!!!!!
40     for(RG int i=0;i<n;i++) { ans[i]=match[i]; if(match[i]==-1) return ; }
41     ok=true; return ;
42     }
43     if(type==1) {//搜第一个
44     if(match[a[x]]!=-1) dfs(x,type+1,remain);
45     else{
46         for(RG int i=n-1;i>=0;i--) {
47         if(vis[i]) continue;
48         vis[i]=1; match[a[x]]=i; dfs(x,type+1,remain);
49         vis[i]=0; match[a[x]]=-1;
50         }
51     }
52     }
53     else{//搜第二个加数的这一位
54     ans1=match[a[x]],ans2=match[b[x]],ans3=match[c[x]];
55     if(ans2!=-1) {
56         RG int sheng=ans1+ans2+remain;
57         if(sheng%n==ans3) dfs(x-1,1,sheng/n);
58         else if(ans3==-1) {
59         vis[sheng%n]=1; match[c[x]]=sheng%n; dfs(x-1,1,sheng/n);
60         vis[sheng%n]=0; match[c[x]]=-1;
61         }
62     }
63     else{
64         RG int cc,ss;
65         for(RG int i=n-1;i>=0;i--) {
66         if(vis[i]) continue;
67         ss=ans1+i+remain; cc=ss%n;
68         if(cc!=ans3 && ans3!=-1) continue;
69         if(ans3==-1) {
70             if(vis[cc]) continue;
71             vis[cc]=1; match[c[x]]=cc;
72         }
73         vis[i]=1; match[b[x]]=i;
74         dfs(x-1,1,ss/n);
75         vis[i]=0; match[b[x]]=-1;
76         if(ans3==-1) {
77             vis[cc]=0; match[c[x]]=-1;
78         }
79         }
80     }
81     }
82 }
83
84 inline void work(){
85     n=getint(); for(RG int i=0;i<=n;i++) match[i]=-1; ce=2*n-2; ce/=n;
86     scanf("%s",ch); for(RG int i=0;i<n;i++) a[i]=ch[i]-‘A‘;
87     scanf("%s",ch); for(RG int i=0;i<n;i++) b[i]=ch[i]-‘A‘;
88     scanf("%s",ch); for(RG int i=0;i<n;i++) c[i]=ch[i]-‘A‘;
89     ok=false; dfs(n-1,1,0);
90     printf("%d",ans[0]); for(RG int i=1;i<n;i++) printf(" %d",ans[i]);
91 }
92
93 int main()
94 {
95   work();
96   return 0;
97 }
时间: 2024-11-06 18:52:06

codevs1064 虫食算的相关文章

CODEVS1064虫食算noip提高组T4

题目描述 Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045    +    8468#6633       44445506978 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光

NOIP2004 虫食算

四.虫食算 (alpha.pas/dpr/c/cpp) [问题描述] 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045     +    8468#6633        44445506978 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许

69. [NOIP2004] 虫食算

69. [NOIP2004] 虫食算 ★★★   输入文件:alpha.in   输出文件:alpha.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045    + 8468#6633 ----------- 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是

深度优先搜索 codevs 1064 虫食算

codevs 1064 虫食算 2004年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045    +    8468#6633       44445506978 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5

noip 虫食算 (搜索)

描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子:43#9865#045+ 8468#6633= 44445506678其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制:首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字

[NOIP2004] 提高组 洛谷P1092 虫食算

题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

洛谷—— P1092 虫食算

https://www.luogu.org/problem/show?pid=1092 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: http://paste.ubuntu.com/25448822/ 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前

虫食算

题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

【NOIP2004】虫食算

Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +   8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的