CODEVS1064虫食算noip提高组T4

题目描述 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个不同的字母分别代表的数字,使得该加法算式成立。输入数据保证有且仅有一组解,

思路:看到题后,就想到了按位搜索,从最低位到最高位,每次搜索都有三种情况(两加数都已有值、一个有、都没有),每种情况又有和有无值得两种情况(我比较丧病,就只想到了这种做法。。。),然后搜索就能过8个点(但是有一个小小的蛋疼的问题,导致我第一次只得了60分,要在输出时判断g是否为0,若不是的话就不满足了)。
加了一个剪枝:没一次进行递归之前都要将比i高的位数都判断一遍,一个judge解决,但是又有一个蛋疼的问题,就是不能只考虑加数加加数等于和的情况,也要考虑加数加加数加1等于和的情况,毕竟会有进位。。。

code:
(写了一个二百行的code,真是醉了。。。)

#include<iostream>

#include<cstring>

#include<cstdio>

using namespace std;

int ans[30]={0},a[30]={0},b[30]={0},c[30]={0},n;

bool f[30]={false},ff=false;

bool judge(int i)

{

int j;

for (j=i+1;j<=n;++j)

{

if (ans[a[j]]!=-1&&ans[b[j]]!=-1&&ans[c[j]]!=-1)

if ((ans[a[j]]+ans[b[j]])%n!=ans[c[j]]&&(ans[a[j]]+ans[b[j]]+1)%n!=ans[c[j]])

return true;

}

return false;

}

void work(int i,int g)

{

int j,k,x,y,z,he;

if (i>n&&g==0)

{

for (j=1;j<=n-1;++j)

cout<<ans[j]<<" ";

cout<<ans[n]<<endl;

ff=true;

return;

}

x=a[i];y=b[i];z=c[i];

if (ans[x]!=-1&&ans[y]!=-1)

{

he=ans[x]+ans[y]+g;

if (he%n==ans[z]&&ans[z]!=-1) work(i+1,he/n);

if (ans[z]==-1)

{

if (!f[he%n])

{

ans[z]=he%n;

f[he%n]=true;

if (!judge(i))

work(i+1,he/n);

if (ff) return;

ans[z]=-1;

f[he%n]=false;

}

}

}

else

{

if (ans[x]==-1&&ans[y]==-1)

{

for (j=0;j<n;++j)

{

if (!f[j])

{

for (k=0;k<n;++k)

if (!f[k])

{

he=j+k+g;

if (ans[z]==-1)

{

if (!f[he%n])

{

ans[z]=he%n;

ans[x]=j;

ans[y]=k;

f[j]=true;

f[k]=true;

f[he%n]=true;

if (!judge(i))

work(i+1,he/n);

if (ff) return;

ans[z]=-1;

ans[x]=-1;

ans[y]=-1;

f[he%n]=false;

f[j]=false;

f[k]=false;

}

}

else

{

if (he%n==ans[z])

{

ans[x]=j;

ans[y]=k;

f[j]=true;

f[k]=true;

if (!judge(i))

work(i+1,he/n);

if (ff) return;

ans[x]=-1;

ans[y]=-1;

f[j]=false;

f[k]=false;

}

}

}

}

}

}

else

{

if ((ans[x]==-1&&ans[y]!=-1)||(ans[x]!=-1&&ans[y]==-1))

{

if (ans[x]!=-1)

{

j=x;x=y;y=j;

}

for (j=0;j<n;++j)

{

if (!f[j])

{

he=ans[y]+j+g;

if (ans[z]!=-1)

{

if (he%n==ans[z])

{

ans[x]=j;

f[j]=true;

if (!judge(i))

work(i+1,he/n);

if (ff) return;

f[j]=false;

ans[x]=-1;

}

}

else

{

if (!f[he%n])

{

ans[z]=he%n;

ans[x]=j;

f[j]=true;

f[he%n]=true;

if (!judge(i))

work(i+1,he/n);

if (ff) return;

ans[z]=-1;

ans[x]=-1;

f[j]=false;

f[he%n]=false;

}

}

}

}

}

}

}

if (ff) return;

}

int main()

{

int i,j;

char ch;

cin>>n;

for (i=1;i<=n;++i)

{

cin>>ch;

a[n-i+1]=ch-‘A‘+1;

}

for (i=1;i<=n;++i)

{

cin>>ch;

b[n-i+1]=ch-‘A‘+1;

}

for (i=1;i<=n;++i)

{

cin>>ch;

c[n-i+1]=ch-‘A‘+1;

}

for (i=1;i<=n;++i)

ans[i]=-1;

work(1,0);

}

时间: 2024-08-29 14:01:36

CODEVS1064虫食算noip提高组T4的相关文章

codevs1064 虫食算

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

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

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

noip 虫食算 (搜索)

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

[NOIP2004]虫食算 T4 简单搜索+剪枝

最近在刷搜索套餐 我先做了一道简单的 虫食算.... 我GO die了........... 这都是啥啊!!!!!!!!!!!!!!! 总之就是一个搜啊.... 从最右面开始搜 每一行行尾进行check 基本上能过9个点........ 剪枝的话 ,考虑检索前面的每一行 如果改行的数字都己经试过,那么就可以判断合法性,如果已经有两个试过的话,考虑第三个数是否可能(可能已经被用过) 注意:试数的时候从后向前试...坑爹的数据 注意进位即可 下面是代码,调试信息懒得删....搜索的第四层可删 略长.

深度优先搜索 codevs 1064 虫食算

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

洛谷—— 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. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

洛谷 P1092 虫食算 Label:dfs

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

Luogu P1092 虫食算

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