http://acm.hdu.edu.cn/showproblem.php?pid=1298
//1254514 2009-04-10 15:46:40 Accepted 1298 0MS 600K 2448 B C++ no way
#include<iostream>
#include<string>
using namespace std;
int i,maxs;
char tel[103];
char seStr[28];
char putss[28];
 char key[10][5] = { {""}, {""}, {"abc1"}, {"def1"},
 {"ghi1"}, {"jkl1"}, {"mno1"},
 {"pqrs"}, {"tuv1"}, {"wxyz"}};

typedef struct dictree
  {
struct dictree *child[26];
int num;
dictree()
 {
for(i=0;i<26;i++)
child[i] = NULL;
num = 0;
}
~dictree()
 {
for(i=0;i<26;i++)
if(child[i] != NULL)
delete child[i];
}
}*dicTree;
dictree *root;
int find(char ch[])//查找单词出现的频率
  {
dictree *p = root;
int k=0,mins = 1000000;
while(1)
 {
if(ch[k]=='\0' || p->child[ch[k]-'a']==NULL)
break;
p = p->child[ch[k]-'a'];
if(mins > p->num)
 {
mins = p->num;
if(mins <= maxs)
return -1;
}
k++;
}
if(ch[k] != '\0')
return -1;
return mins;
}

void dfs(int p,int t,int k)//深搜,t-界限,p-串中位置
  {
int j;
if(p>t)
 {
seStr[k]='\0';
int m = find(seStr);
if(m > maxs)
 {
strcpy(putss,seStr);
maxs = m;
}
return ;
}
for(j=0;j<4;j++)
 {
if(key[tel[p]-'0'][j] != '1')
 {
seStr[k] = key[tel[p]-'0'][j];
seStr[k+1]='\0';
if(find(seStr) <= maxs) //该剪枝非常重要
continue;
dfs(p+1,t,k+1);
}
}
}

void insert(char *s,int r) //构建字典树
  {
struct dictree *now = root;
while(*s)
 {
if(now->child[*s-'a'] == NULL)
now->child[*s-'a'] = new dictree;
now = now->child[*s-'a'];
now->num += r;
s++;
}
}
 /**//*
void Delete(dicTree &pt)
{
if(pt)
{
for(i=0;i<26;i++)
Delete(pt->child[i]);
}
free(pt);
pt = NULL;
}
*/
int main()
  {
int j,n,r,t,cas=1;
char tmp[103];
cin>>t;
while(t--)
 {
cin>>n; //单词的个数
root = new dictree;
while(n--)
 {
scanf("%s%d",tmp,&r);
insert(tmp,r);
}
cin>>n; //电话串的个数
cout<<"Scenario #"<<cas++<<":"<<endl;
while(n--)
 {
scanf("%s",tel);
int len = strlen(tel);
for(j=0;j<len;j++)
 {
if(tel[j] == '1')//结束符
break;
if(j>25)//大于26个就没必要做了,肯定是没这个串
 {
printf("MANUALLY\n");
continue;
}
maxs = -1;
dfs(0,j,0);
if(maxs == -1)
printf("MANUALLY\n");
else
printf("%s\n",putss);
}
printf("\n");
}
printf("\n");
//Delete(root);
}
return 0;
}
|