Equation
Equation ( equation )
【题目描述】
给定一个等式,其格式为 p ◦ q = r,其中 1 ≤ p,q,r < 10 9 ,算符 ◦ 可以是 +、- 或
*(表示乘法)。
p,q 和 r 中的某些数字被替换成了大写字母,例如 A09 + C0B = 6AC。你的任务
是找出所有大写字母代表的数字,使得等式成立。
你需要遵循下列规则:
1. 相同的字母替换成相同的数字,不同的字母替换成不同的数字。
2. p、q 和 r 不能以 0 开头。
称两个方案不同,如果存在一个字母被替换成了不同的数字。考虑到方案数可能很
多,你只需要输出合法方案的数量。注意如果没有方法使得等式成立,你应该输出 0。
【输入格式】
从文件 equation.in 中读入数据。
输入只有一行,表示需要处理的等式。
保证最多只有 9 个不同的字母,等式中不会出现空格。
【输出格式】
输出到文件 equation.out 中。
输出一个整数,表示方案的数量。
【样例 1 输入】
A09+C0B=6AC
【样例 1 输出】
1
【样例 1 解释】
唯一合法的方案是 109 + 506 = 615。
【样例 2 输入】
P*Q=P
第 5 页 共 8 页
NOIP 模拟题 Equation(equation)
【样例 2 输出】
8
【样例 3 输入】
CANADA-MAR8=CCC
【样例 3 输出】
0
【子任务】
总共有 10 个测试点。
对于测试点 1 ∼ 3,等式中最多有 3 个不同的字母。
对于测试点 1、2、4、7 和 8,◦ 只可能是 + 或 -。
对于测试点 1、4、5 和 6,每个字母只会出现一次。
找遍了我知道的所有的OJ,发现并没有这道题
很苦逼的找了AC代码对拍,然后发现我考场上发一个字符打了两遍,只有70pts,心态崩了
好像还T了一个点,pow函数是真的慢
题不是很难,爆搜,枚举每个字母的数字,其实就是一个全排列,卡卡常就行
网上没什么好的数据,我就随便给一发:
输入:
ABCDEFGH-BCDEFGH=AIIIIIII
输出:
362880
下面给出代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> using namespace std; inline long long rd(){ long long x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } inline void write(long long x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return ; } char a[10006]; bool book[10006]; long long h[100006]; char vis[10006]; int cnt; int len=0,fir,sec,f=0; long long ans=0; bool map[100006]; long long s[10006]; long long p[10006]; inline long long check(){ long long A=0,b=0,c=0; int set=fir; while(set--){ if(set==0) break; if(isdigit(a[set])) A+=((a[set]-'0')*p[fir-set-1]); else A=A+(s[a[set]-'0']*p[fir-set-1]); } set=sec; while(set--){ if(a[set]=='+'||a[set]=='-'||a[set]=='*') break; if(isdigit(a[set])) b+=((a[set]-'0')*p[sec-set-1]); else b=b+(s[a[set]-'0']*p[sec-set-1]); } for(register int j=len;j>sec;j--){ if(isdigit(a[j])) c+=((a[j]-'0')*p[len-j]); else c=c+(s[a[j]-'0']*p[len-j]); } if(f==1&&A-b==c) return 1; if(f==2&&A+b==c) return 1; if(f==3&&A*b==c) return 1; return 0; } inline void dfs(int x){ if(x==cnt+1){ if(check()) ans++; return ; } for(register int i=0;i<=9;i++){ if(i==0&&h[vis[x]-'0']) continue; if(map[i]) continue; map[i]=1; s[vis[x]-'0']=i; dfs(x+1); s[vis[x]-'0']=-1; map[i]=0; } return ; } int main(){ //freopen("equation.in","r",stdin); //freopen("equation.out","w",stdout); p[0]=1; for(int i=1;i<=10;i++) p[i]=p[i-1]*10; memset(s,-1,sizeof(s)); scanf("%s",a+1); len=strlen(a+1); for(register int i=1;i<=len;i++){ if(a[i]=='-') f=1; if(a[i]=='+') f=2; if(a[i]=='*') f=3; if(a[i]=='-'||a[i]=='+'||a[i]=='*') fir=i; if(a[i]=='=') sec=i; if(book[a[i]-'0']==0){ book[a[i]-'0']=1; if(a[i]!='+'&&a[i]!='*'&&a[i]!='-'&&a[i]!='='&&!isdigit(a[i])) vis[++cnt]=a[i]; } if(i==1||a[i-1]=='='||a[i-1]=='+'||a[i-1]=='-'||a[i-1]=='*') h[a[i]-'0']=1; } dfs(1); write(ans); return 0; }