写在前: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;
}