USACO习题:Name That Number

这道题或许是这个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;
}



转载于:https://www.cnblogs.com/lzyzizi/archive/2012/03/26/2417565.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值