北邮OJ 981. 16校赛-Saber's Number Game

来源:互联网 发布:国际淘宝网官方网站 编辑:程序博客网 时间:2024/05/05 17:14

题目描述

       Saber is fond of number games of various kinds, she particularly likes a kind of number-guessing game. The game is played in pairs, one player decides an integer X without leading zeros, and writes it down on the paper twice with part of its numbers coded by upper case letters. The rule goes that the same letter can only represent same digit. For example, the number 1010 can be written in the form of 1XYX and 1A10, or AB10 and C0AB. The other player has to guess the original number. In both cases, 1010 is the only answer.

       Unfortunately, in most cases, there are more than one answer to the question, sometimes due to miscoding there is just no solution at all. Saber wants to know the total number of integers that can be the correct answer to the codes written on the paper, so that she can figure out how many times at most she would guess.

 

 

输入格式

       The input begins with a line containing a single integer T(1T200), indicating the number of test cases. For each test case, the first line contains one integers N, indicating the number of digits of the integer to be guessed. The next two lines each contains a string containing N(2N18) characters, describing the codes written on the paper. It is guaranteed that the strings would only contain digits and upper case letters.

输出格式

       For each test case, print a single line with one integer, indicating the number of integers that can be the correct answer. If there are no solutions, please output '0' without quotes!

输入样例

341XYX1A103XXXYYY8TOOYOUNGTOONAIVE

输出样例

1990000
题意是给两个字符串,上下对应位置的字母和数字之间相互等同,没有数字对应的字母可以等价于任意数字,但字符串整体来看不能有前导0,求所有的字符串可能代表的数字的数量,例如

1XYX

1A10

X等价于A,Y等于1,X等于0,所有A等于0,所以答案是1,因为只有一种可能性。

XXX

YYY

X等价于Y,然而他们可以等价于任意数字,但是不能等于0,不然就变成了000,不符合要求,所以答案是9

TOOYOUNG

TOONA I VE

Y等于N,O等于A,U等于I,N等于V,所以Y等于N等于V,G等于E,首字母T只能等于1-9,O和A任意0-10,Y、N、V任意0-10,U和I任意0-10,G和E任意0-10,这样9*10*10*10*10=90000

最先想到的是并查集,或者直接bfs搜索也行。

初始化parent[i]=i

从字符串位置0开始,同时检查两个字符串相同位置,如果是数字而且不同,那么直接answer=0;如果是数字和字母,那么让字母的parent等于数字;如果都是字母,跑并查集,检查双方的parent,如果都已经有数字,但是不同,那么直接answer=0,如果不是,将靠后字母的parent设为靠前字母的parent。当位置0的时候,给字符打一个起始位置的标记sig=1,以便后来检查前导0。


最后,设answer=1,再从0开始,检查当前位的字母的parent,如果是数字,那就*1;如果是数字0,那就answer=0;如果是字母而且是自己本身而且没有使用过,那就*10(比如A=B,字符串为AB,那么在A的位置上*10,在B的位置上就不再处理了,因为A=B);但如果是开头第一位,那就*9。

#include<cstdio>#include<cmath>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#define clr0(a) memset(a,0,sizeof a)#define clr1(a) memset(a,1,sizeof a)#define ini(a) memset(a,-1,sizeof a)#define N 150 using namespace std; char a[50],b[50];int n,pa[N],vis[N],sig[N],rec[N]; int f(int x){return pa[x]==x?x:pa[x]=f(pa[x]);}int main(){    int i,t,j,n;    for(scanf("%d",&t);t--;){        clr0(vis);clr0(sig);ini(rec);        scanf("%d",&n);        scanf("%s%s",a,b);        for(i=0;i<150;i++){            pa[i]=i;        }        for(i=48;i<58;i++){            rec[i]=i-48;        }        long long res=1;        for(i=0;i<n;i++){            int px,py;            if(a[i]<='9'&&a[i]>='0'&&b[i]<='9'&&b[i]>='0'&&a[i]!=b[i]){                res=0;                goto out;            }else{                px=f(a[i]);                py=f(b[i]);                if(px!=py){                    if(rec[px]!=rec[py]&&rec[px]!=-1&&rec[py]!=-1){                        res=0;                        goto out;                    }else{                        pa[py]=px;                        rec[px]=rec[px]>rec[py]?rec[px]:rec[py];                        if(sig[py]==1)                            sig[px]=1;                    }                }            }            if(i==0){                sig[px]=1;            }        }        if(rec[f(a[0])]==0){            res=0;            goto out;        }        for(i=0;i<n;i++){            if(f(a[i])==a[i]){                if(vis[a[i]]==0){                    if(rec[a[i]]==-1){                        if(sig[a[i]]==1){                            res=res*9;                        }else{                            res=res*10;                        }                    }                    vis[a[i]]=1;                }            }        }        out:            printf("%lld\n",res);    }    return 0;}


0 0
原创粉丝点击