您的位置:首页 > 其它

Problem 29 Name That Number

2006-01-24 01:17 267 查看
这又是一个简单的全搜索,给出一个数字,每个数字可以对应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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: