这道题或许是这个SEC里最有难度的题目了。题目有些误导,让你用数字先生成所有可能的字母,然后再去字典里找。
这种做法的复杂度随着数字的长度n的上升而上升,为O(3^n)是非常可怕的,而且生成不同长度的字母,需要根据数字长度决定循环的数量,
这里就会用到递归,使得代码变得异常复杂。
静下来仔细想想,每组数字可以对应多个单词,同样的,每个单词回应一个数字。换句话说,我们可以轻松得为字典中每个单词先生成一遍
数字,然后根据数字去反查单词。这样代码的速度就非常快了,而且一旦生成好对应,以后任何数字的匹配时间基本等于一次哈希的时间即O(1)。
注:在单词转数字的时候,使用一些数学的小技巧可以有效地节省不少代码(对于我这种懒人来说非常合适)。
View Code
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
string name2number(string name){
char c=0;
int value=0;
ostringstream buf;
for(string::iterator iter=name.begin();iter!=name.end();iter++){
c=*iter;
if(c>'Q'){
value = (c-1-'A')/3 + 2;
}else{
value = (c-'A')/3 + 2;
}
buf<<value;
}
return buf.str();
}
int main() {
ofstream fout("namenum.out");
ifstream fin("namenum.in");
ifstream dict_fin("dict.txt");
string value;
fin>>value;
//cout<<value<<endl;
string name;
bool not_found=true;
while(dict_fin>>name){
string number = name2number(name);
//cout<<"name:"<<name<<"-->"<<number<<endl;
if(number != value)
continue;
fout<<name<<endl;
not_found=false;
}
if(not_found)
fout<<"NONE"<<endl;
dict_fin.close();
fin.close();
fout.close();
return 0;
}