USACO Name That Number

来源:互联网 发布:超级大乐透数学算法 编辑:程序博客网 时间:2024/05/15 11:09

【题意】

在dict.txt中给定字典,然后给出数字2-9,每个数字可以变成某些英文(如下表),然后按照字典序输出所有在dict的变换

变换规则:

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

【分析】

多个文件读入,C++的俺不会,就用回C的好了。

首先从dict.txt读入,存到一棵字典树上(PS:完全不用吧,不过我习惯了......)

不得不吐槽一下万恶的空间限制,本题又不给定,又要判我trie开了1000000空间太大,直接TLE了三次,然后改成100000就没事了...

字典树搞好了,然后就读入namenum.in里的数字,用字符串存储。

反正才长11位,那就直接搜索算了,反正字典树满足字典序(PS:不过给的数据好像就满足......),找到一个输出一个。

【实现】

/*

{

ID:y2007031

PROG:namenum

LANG:C++

}

*/


#include <cstdio>

#include <cstring>

#include <cstdlib>


using namespace std;


const char dx[10][5]={"NNN","NNN","ABC","DEF","GHI","JKL","MNO","PRS","TUV","WXY"};


FILE *inf,*ouf;

struct T

{

int next[26],has;

}tr[100000];

int tot=1;

char res[14],s[14];

int len;


inline void ins_trie(void)

{

len=strlen(s);

int now=1;

for (int i=0;i<len;i++)

{

int nxt=s[i]-'A';

if (!tr[now].next[nxt]) tr[now].next[nxt]=++tot;

now=tr[now].next[nxt];

}

tr[now].has++;

}


int DFS(int now,int dep)

{

if (!now) return 0;

if (dep==len)

{

if (tr[now].has) fprintf(ouf,"%s\n",res);

return 1;

}

int d=0;

for (int i=0;i<3;i++)

{

res[dep]=dx[s[dep]-'0'][i];

d|=DFS(tr[now].next[res[dep]-'A'],dep+1);

res[dep]=0;

}

return d;

}


int main(void)

{

inf=fopen("dict.txt","r");

for (;;)

{

if (!~fscanf(inf,"%s",s)) break;

ins_trie();

}

fclose(inf);

inf=fopen("namenum.in","r");

ouf=fopen("namenum.out","w");

fscanf(inf,"%s",s);

len=strlen(s);

if (!DFS(1,0)) fprintf(ouf,"NONE\n");

fclose(inf);

fclose(ouf);

return 0;

}


0 0
原创粉丝点击