poj 2503 Babelfish 【二分 + 排序】

题目链接:http://poj.org/problem?id=2503

Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 49930 Accepted: 20825

Description

You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language. Fortunately, you have a dictionary to help you understand them.

Input

Input consists of up to 100,000 dictionary entries, followed by a blank line, followed by a message of up to 100,000 words. Each dictionary entry is a line containing an English word, followed by a space and a foreign language word. No foreign word appears more than once in the dictionary. The message is a sequence of words in the foreign language, one word on each line. Each word in the input is a sequence of at most 10 lowercase letters.

Output

Output is the message translated to English, one word per line. Foreign words not in the dictionary should be translated as "eh".

Sample Input

dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay

atcay
ittenkay
oopslay

Sample output

cat
eh
loops

题意(来源有道翻译):

Description

你刚从滑铁卢搬到一个大城市。这里的人说着一种听不懂的外语方言。幸运的是,你有一本字典来帮助你理解它们。

Input

输入由多达100,000个字典条目组成,后面是一个空行,后面是最多100,000个单词的消息。每个字典条目是一行包含一个英语单词,后面跟着一个空格和一个外语单词。字典里没有外来词出现过一次。信息是一串外语单词,每行一个单词。输入中的每个单词最多是10个小写字母的序列。

Output

输出是翻译成英语的消息,每行一个单词。词典中未收录的外来词应译为“eh”。

分析 :这道题容易想到枚举方法解决,就是从消息中取一个单词,然后遍历整个字典,看是否与字典里面的单词匹配,但是这样操作下来的复杂度是O(n^{2}),对于这道输入包括100000个数据,肯定会TLE。所以我们的目标就是要用二分进行解决,别忘了二分能将算法的复杂度降至log_{2}(n)

还有一个难点就是数据的读入问题(难了我半天,汗~~):

因为消息中每行只有一个单词,然后是换行,而字典中则是两个单词中间一个空格,因此可以先读入一个单词和一个字符,如果该字符为空格,则说明仍在读入字典,如果是回车换行,则是读到了消息,这是就可以结束字典读入!

下面附上我的AC代码:

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 20;
int pos;
struct inp{
    char w[maxn]; //存储外文
    char e[maxn]; //存储英文
}dic[100000+100];
bool cmp(inp a,inp b)
{
    return strcmp(a.w,b.w) < 0;
}
int binsearch(char *s)
{
    int l = 0,r = pos - 1;
    while(l <= r)
    {
        int mid = (l + r) / 2;
        if(strcmp(dic[mid].w,s) > 0)
            r = mid - 1;
        else if(strcmp(dic[mid].w,s) < 0)
            l = mid + 1;
        else
            return mid; //如果两者相等,那么返回mid的值,即是查找的外文单词所在的位置,一定是>=0
    }
    return -1; //如果查找不到,返回一个负值,这对应着输出eh的情况
}
int main()
{
    char s1[maxn],s2[maxn],c;
    pos = 0;
    while(~scanf("%s%c",dic[pos].e,&c)) //体会下输入的技巧
    {
        if(c == '\n')
        {
            strcpy(s2,dic[pos].e);
            break;
        }
        scanf("%s",dic[pos++].w);
    }
    sort(dic,dic+pos,cmp);
    int num = binsearch(s2);
    if(num >= 0)
        printf("%s\n",dic[num].e);
    else
        puts("eh");
    while(~scanf("%s",s1))
    {
        int num = binsearch(s1);
        if(num >= 0)
            printf("%s\n",dic[num].e);
        else
            puts("eh");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值