Problem 29 Name That Number

这又是一个简单的全搜索,给出一个数字,每个数字可以对应3个字母,象这样: 2: A,B,C    3: D,E,F    4: G,H,I 等等。。。

再给一个字典,找到这个数字所有的可能性以后再查字典,选出字典里有的词,输出。字典由usaco给出,差不多4千多个词。

最直观的方法就是构建所有的组合,再去查字典。构建的花样不多,查字典的时候小心效率。由于字典是有序的,两分法应该是最好的。

或者反过来,把字典里的词取出来构建数字看符不符合给出的数字。两种方法都可以达到很高的效率。前面一种稍微考点功夫。

我起初用了STL的容器set来放字典,超时~。后来发现字典有序,set毫无意义,换成vector,效率提高10%,依然超时,郁闷~。再换成普通数组,OK,速度翻倍!对比检验网站提供的解法,发现还是比它慢:(貌似string的效果也不理想,还是char*最快。。。

#include <iostream>
#include <fstream>
#include <string>
#include <cmath> // for pow()
using namespace std;

int main(){
 char alphabet[10][3] = {{},{},{'A','B','C'},{'D','E','F'},
    {'G','H','I'},{'J','K','L'},{'M','N','O'},
    {'P','R','S'},{'T','U','V'},{'W','X','Y'}};
 char sn[13]; // 12+1, plus 1 for '/0'
 string name;
 ifstream fin("namenum.in");
 fin.get(sn, 13);
 
 ofstream fout("namenum.out");
 int count = 0;

 ifstream fdict("dict.txt");
 string pname;
 string dict[5000];
 int dp = 0;
 while(getline(fdict, pname)) dict[dp++] = pname;
 
 int i = (int)strlen(sn);
 int* arr = new int[i];
 memset(arr, 0, i * sizeof(int));
 int pos = 0;
 int upper = (int)pow((double)3, i);
 char* tname = new char[13];
 for(int it = 0; it < upper; ++it){
  for(int index = i - 1; index >=0; --index){
   if(arr[index]>2){
    arr[index]=0;
    ++arr[index-1];
   }else break;
  }
  for(int j = 0; j < i; ++j)
   tname[j]=alphabet[sn[j] - 48][arr[j]];
  tname[i]='/0';
  string name(tname);
  while(name > dict[pos]) ++pos;
  if(name == dict[pos]){
   fout<<name<<endl;
   ++count;
  }
  ++arr[i - 1];
 }
 if(count == 0) fout<<"NONE"<<endl;
}

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值