【字符串匹配_哈希】HDU 1880 魔咒词典(太难了,我上辈子是个南瓜,TAT,改了一下午,竟然是读错题)

 写在前:Curse: 诅咒     Function: 功能【今天这两个我认识,让我骄傲一波23333333】


HDU 1880 魔咒词典

  • 题意:Harry Potter有一本词典,内容是[魔咒]<-->功能。然后我们有T次询问,问输入的内容词典中有没有对应内容(魔咒对应功能,功能对应魔咒)。如果有,输出对应内容;如果没有,输出"what?"
  • 思路:分别算出魔咒的哈希、功能的哈希。然后用map<ull, string>存<魔咒哈希值, 功能字符串> <功能哈希值, 魔咒字符串>。每次询问就是log的查找输出。
  • 这个比较繁琐的就是字符串的读入。我的做法是直接gets整个字符串,然后再遍历一遍用string存魔咒字符串(带着'[' ']')和功能字符串。如果输出魔咒字符串的话就用string的函数substr输出不带'[',']'的子串即可。
  • !!!!!一定不能输出前后的方括号,我就是一直WA一直WA,也从来没看见过样例给的答案是不带方括号的。结果百度看大佬博客无果就去找人帮我debug。他问我你什么问题?我说WA了,他说你样例都没过,怎么可能AC?TAT,我太难了,我真的改了一下午啊TAT,头疼TAT. 
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define lowbit(x) x & (-x)

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 1e5 + 5;
const ull base = 23;

map<ull, string> fir, sec;
char s[maxN];
ull G_hash(string str)
{
    int len = str.size(); ull ans = 0;
    for(int i = 0; i < len; i ++ )
        ans = ans * base + str[i];
    return ans;
}
int main()
{
    while(gets(s) && strcmp(s, "@END@") != 0)
    {
        int len = strlen(s);
        int i = 0;
        string curse, func;
        for(; s[i] != ']'; i ++ )
            curse += s[i];
        curse += ']';
        for(i += 2; i < len; i ++ )
            func += s[i];
        fir[G_hash(curse)] = func;
        sec[G_hash(func)] = curse;
    }
    int TAT; scanf("%d", &TAT); getchar();
    while(TAT -- )
    {
        gets(s);
        string str = s;
        ull Hash_s = G_hash(str);
        map<ull, string>:: iterator it;
        if(str[0] == '[')
        {
            it = fir.find(Hash_s);
            if(it != fir.end())
                cout << it->second << endl;
            else
                cout << "what?" << endl;
        }
        else
        {
            it = sec.find(Hash_s);
            if(it != sec.end())
                cout << it->second.substr(1, it->second.size() - 2) << endl;
            else
                cout << "what?" << endl;
        }
    }
    return 0;
}

 这是最开始写的,难看的一批。我自己都不想看……

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define lowbit(x) x & (-x)

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 1e5 + 5;
const ull base = 2333;
struct node{
    string fir;
    char sec[100];
    ull hash_fir, hash_sec;
}info[maxN];
struct dot{
    ull hash;
    int id;
    friend bool operator < (dot d1, dot d2) { return d1.hash < d2.hash; }
};
set<dot>fir, sec;
int main()
{
    int cnt = 0;
    while(cin >> info[++ cnt].fir && info[cnt].fir != "@END@")
    {
        while(info[cnt].fir[info[cnt].fir.size() - 1] != ']')
        {
            info[cnt].fir += ' ';
            string tmp; cin >> tmp;
            info[cnt].fir += tmp;
        }
        int len_fir = info[cnt].fir.size();
        info[cnt].hash_fir = 0;
        for(int i = 0; i < len_fir; i ++ )
            info[cnt].hash_fir = info[cnt].hash_fir * base + info[cnt].fir[i];
        getchar();
        gets(info[cnt].sec);
        int len_sec = strlen(info[cnt].sec);
        info[cnt].hash_sec = 0;
        for(int i = 0; i < len_sec; i ++ )
            info[cnt].hash_sec = info[cnt].hash_sec * base + info[cnt].sec[i];
        fir.insert(dot{info[cnt].hash_fir, cnt});
        sec.insert(dot{info[cnt].hash_sec, cnt});
    }
    int TAT; scanf("%d", &TAT); getchar();
    while(TAT -- )
    {
        char q[100];
        gets(q);
        ull hash_q = 0; int len = strlen(q);
        for(int i = 0; i < len; i ++ )
            hash_q = hash_q * base + q[i];
        set<dot>::iterator it;
        it = fir.find(dot{hash_q, 0});
        if(it != fir.end())
        {
            cout << info[(*it).id].sec << endl;
            continue;
        }
        it = sec.find(dot{hash_q, 0});
        if(it != sec.end())
        {
            cout << info[(*it).id].fir.substr(1, info[(*it).id].fir.size() - 2) << endl;
            continue;
        }
        printf("what?\n");
    }
    return 0;
}
发布了190 篇原创文章 · 获赞 57 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/104071375