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