namenum-section1.2

来源:互联网 发布:做假章软件 编辑:程序博客网 时间:2024/06/07 08:43

题目大意

每头牛都有一个数字编号,现在要根据这个数字编号给牛取名字,每个数字对应有三个字母,牛的名字中的每个字母取数字编号中每个数字对应的三个字母中的某一个。同时要求牛的名字必须要在一本花名册中存在,否则视为非法名字。花名册中名字个数大概有5000个,数字编号的长度为N,且1<=N<=12;数字对应的字母如下: 2: A,B,C     5: J,K,L    8: T,U,V 3: D,E,F     6: M,N,O    9: W,X,Y 4: G,H,I     7: P,R,S 花名册在文件dict.txt中。

输入格式

line 1:一行数字编号

输出格式

所有满足数字编号翻译且在花名册中存在的合法名字,一行一个,按字典序排列。没有合法的名字则输出NONE。

样例输入

4734

样例输出

GREG

题解

    看见这个题第一反应:每个数字对应三种情况(三个字母),将编号中每个数字对应的字母全排列,即获得所有该数字编号可能对应字母名字;再将这所有的可能的字母名字,在花名册中搜索,判断是否存在于花名册中;最后将所有合法的名字按字典序排列输出。    以上是很自然的根据数字找字母的想法,可惜由于全排列,测试时很容易运行超时。然后便是复杂的剪枝工作。考虑效率原因,可以换种思路:    既然可以由数字找名字,同样也可以由名字找数字。易知合法的名字全部在花名册中,可以将花名册的名字根据数字字母对应关系转化成数字,再和输入的数字编码对比,选出合法的名字,最后按字典序输出。    另外,可以根据数字编码的长度可以只在花名册中挑选长度相同的名字翻译成数字,依此可以节约时间(此题中没多大区别。。。)

代码

#include<stdio.h>#include<string.h>int main(){FILE *fd=fopen("dict.txt","r");char dt[5000][20],dtn[5000][20];int i,j,flag,l,flag1=0;for(i=0;i<5000;i++){    fscanf(fd,"%s",dt[i]);}char number[12];scanf("%s",number);int len,len1,count=0;len=strlen(number);for(i=0;i<5000;i++){    len1=strlen(dt[i]);    if(len1==len)    {        for(j=0;j<len;j++)        dtn[count][j]=dt[i][j];        count++;    }}for(i=0;i<count;i++){    flag=1;    for(j=0;j<len;j++)    {        l=dtn[i][j]-'A';        if(dtn[i][j]-'Q'>0)            l=l-1;        if((l/3+2)!=(number[j]-'0'))        {flag=0;break;}    }    if(flag==1)    {for(j=0;j<len;j++)       printf("%c",dtn[i][j]);    printf("\n");    flag1=1;}}if(flag1==0){    printf("NONE\n");}return 0;}
原创粉丝点击