码迷,mamicode.com
首页 > 其他好文 > 详细

Equation

时间:2018-10-06 13:26:25      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:char   pre   scan   stdin   ati   相同   bsp   memset   表示   

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;
}

 

Equation

标签:char   pre   scan   stdin   ati   相同   bsp   memset   表示   

原文地址:https://www.cnblogs.com/WWHHTT/p/9746895.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!