虫食算
来源:互联网 发布:la域名在里注册便宜 编辑:程序博客网 时间:2024/06/06 02:43
☆虫食算 描述 Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子:
43#9865#045
+ 8468#6633
= 44445506678
其中#号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5。
现在,我们对问题做两个限制:
首先,我们只考虑加法的虫食算。这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0。
其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同的数字用不同的字母表示。如果这个算式是N进制的,我们就取英文字母表午的前N个大写字母来表示这个算式中的0到N-1这N个不同的数字:但是这N个字母并不一定顺序地代表0到N-1)。输入数据保证N个字母分别至少出现一次。
BADC
+ CRDA
= DCCC
上面的算式是一个4进制的算式。很显然,我们只要让ABCD分别代表0123,便可以让这个式子成立了。你的任务是,对于给定的N进制加法算式,求出N个不同的字母分别代表的数字,使得该加法算式成立。输入数据保证有且仅有一组解 输入格式 Input Format 输入包含4行。第一行有一个正整数N(N<=26),后面的3行每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这3个字符串左右两端都没有空格,从高位到低位,并且恰好有N位。 输出格式 Output Format 输出包含一行。在这一行中,应当包含唯一的那组解。解是这样表示的:输出N个数字,分别表示A,B,C……所代表的数字,相邻的两个数字用一个空格隔开,不能有多余的空格。 输入输入:
5
ABCED
BDACE
EBBAA
输出:
1 0 3 4 2
最基本的搜索,按合理的搜索顺序(从后向前),精妙的剪枝(三个确定两个,判断。一个数之前用过,退出。第一个等于第三个,第二个则等于0或n-1...)就可以AC了
半AC代码:
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>#include<cmath>using namespace std;string s1,s2,s3;int n,a[30],b[50]={};int c[30]={},d[30]={};int dfs(int k);int lll(int ch1,int ch2,int ch3,int k){if(c[ch3]==1){if((a[ch1]+a[ch2]+b[k])%n!=a[ch3]) return 0;b[k-1]=(a[ch1]+a[ch2]+b[k])/n;dfs(k-1);}else{a[ch3]=(a[ch1]+a[ch2]+b[k])%n;b[k-1]=(a[ch1]+a[ch2]+b[k])/n;if(d[a[ch3]]==1){b[k-1]=0;return 0;}c[ch3]=1;d[a[ch3]]=1;dfs(k-1);c[ch3]=0;d[a[ch3]]=0;a[ch3]=-1;}return 0;}int dfs(int k){ if(k==-1&&b[k]==0) {for(int i=0;i<n;i++)cout<<a[i]<<' ';cout<<endl;/*for(int i=0;i<n;i++)cout<<b[i]<<' ';*/exit(0); }int ch1=s1[k]-'A';int ch2=s2[k]-'A';int ch3=s3[k]-'A'; if(c[ch1]==1&&c[ch2]==1) { lll(ch1,ch2,ch3,k);/*if(c[ch3]==1) { if((a[ch1]+a[ch2]+b[k])%n!=a[ch3]) return 0; b[k-1]=(a[ch1]+a[ch2]+b[k])/n; dfs(k-1); } else { a[ch3]=(a[ch1]+a[ch2]+b[k])%n; b[k-1]=(a[ch1]+a[ch2]+b[k])/n; if(d[a[ch3]]==1) {b[k-1]=0; return 0; } c[ch3]=1; d[a[ch3]]=1; dfs(k-1); c[ch3]=0; d[a[ch3]]=0; a[ch3]=-1; }*/ } else {if(c[ch1]==1&&c[ch2]!=1){/*if(c[ch3]==1){a[ch2]=a[ch3]-b[k]-a[ch1];if(a[ch2]<0)a[ch2]+=n;if(d[a[ch2]]==1){a[ch2]=-1;return 0;}c[ch2]=1;d[a[ch2]]=1;dfs(k-1);c[ch2]=0;d[a[ch2]]=0;a[ch2]=-1;goto trans;}*/ for(int i=n-1;i>=0;i--) { if(d[i]!=1) { d[i]=1; a[ch2]=i; c[ch2]=1; //dfs(k);lll(ch1,ch2,ch3,k); d[i]=0; a[ch2]=-1; c[ch2]=0; } }trans:{}}else {if(c[ch2]==1&&c[ch1]!=1){/*if(c[ch3]==1){a[ch1]=a[ch3]-b[k]-a[ch2];if(a[ch1]<0)a[ch1]+=n;if(d[a[ch1]]==1){a[ch1]=-1;return 0;}c[ch1]=1;d[a[ch1]]=1;dfs(k-1);d[a[ch1]]=0;c[ch1]=0;a[ch1]=-1;goto trans1;}*/for(int i=n-1;i>=0;i--){if(d[i]!=1){d[i]=1;c[ch1]=1;a[ch1]=i;//dfs(k);lll(ch1,ch2,ch3,k);d[i]=0;c[ch1]=0;a[ch1]=-1;}}trans1:{}}else {for(int i=n-1;i>=0;i--)if(d[i]!=1) {d[i]=1;c[ch1]=1;a[ch1]=i;dfs(k);//lll(ch1,ch2,ch3,k);a[ch1]=-1;d[i]=0;c[ch1]=0;}}}}return 0;}int main(){ //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); memset(a,-1,sizeof(a));cin>>n;cin>>s1>>s2>>s3; dfs(n-1); return 0;}为什么是半AC呢?因为在洛谷上提交有一测试点过不了,可是在本校oj上AC了...
垃圾本校OJ,吃枣药丸
然而...
洛谷上还没有过...
0 0
- 虫食算
- 虫食算
- 虫食算
- 虫食算
- 虫食算
- 虫食算
- 虫食算
- 虫食算
- 虫食算
- 虫食算
- noip 虫食算
- Noip2004T4 虫食算
- NOIP2004虫食算
- NOIP2004 虫食算
- 【NOIP2004】虫食算
- NOIP2004【虫食算】
- 搜索--虫食算
- 【高斯消元】虫食算
- java 方法中 参数的复制
- 九.Spring 实体管理器
- JavaScript学习笔记22-事件处理
- Oracle之escape关键字(转义字符)
- bugzilla
- 虫食算
- Oracle 中循环遍历某张表,并对符合条件的进行Update操作
- Oracle入门____创建表空间,创建用户,赋权
- vagrant box 相关调查记录
- sdut 2153 Clockwise
- ORACLE中SID和SERVICE_NAME的区别
- 《APUE》读书笔记-第十五章进程间通信
- Nagle Algorithm
- Android主流网络请求开源库的对比(Android-Async-Http、Volley、OkHttp、Retrofit)