<题目链接>
题目大意:
就是每个字符串有一个配套的对应字符串,询问的时候,无论输出其中的哪一个字符串,输出另一个,如果不存在这个字符串,直接输出"what?"。
解题分析: 转载于 >>>
本题很明显要用字符串hash,数据量比较大,如果直接用map,会Mle。所以我们用hash表来处理,下面采用了一个比较优秀的hash算法-BKDR进行处理。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 2e6 + 100; const int MOD = 1e6 + 7; const int BASE = 131; struct Node{ char s[100]; Node* next; }Hashpos[MAXN], *head[MOD], *now; //BKDRHash算法是字符串hash算法。是一种比较优秀的hash算法 int Get_Id(char *s){ //得到字符串hash后的hash值 int Hash = 0; int len = strlen(s); for(int i = 0 ; i < len ; i++) Hash = (Hash * BASE % MOD + s[i]) % MOD ; return Hash; } void BKDRHashpos(char *s){ int code = Get_Id(s); Node* p = head[code];//取的是地址(以该code为头标志的最后一个数的地址) while(p){ //如果没有到达头标志一直往上 if(!strcmp(p->s, s)) //如果hash地址相同的链表上有这个元素,直接返回 return; else p = p->next; //如果没有这个元素,就一直向后查找,直至放在链表的尾部 } strcpy(now->s, s); //将这个元素插入当前位置(最后一个位置) now->next = head[code]; //记录这个数上一个的地址,就是与链式前向星的作用类似 head[code] = now++; //更新这个code所对应的最后一个数的地址 } int find(char *s){ int code = Get_Id(s); Node* p = head[code]; while(p){ if(!strcmp(p->s, s))return p-Hashpos; //p为当前串在哈希表上的地址,Hashpos是初始地址 else p = p->next; } return -1; } int main(){ now = Hashpos; char str[100]; while(~scanf("%s", str)){ if(!strcmp(str,"@END@"))break; getchar(); BKDRHashpos(str); gets(str);BKDRHashpos(str); } int q;scanf("%d",&q);getchar(); while(q--){ gets(str); int id = find(str); if(id==-1) puts("what?"); else{ char *node = Hashpos[id^1].s; //因为是从0开始 两两 存储,所以这里直接取异或 if(node[0]=='['){ for(int i=1;node[i]!=']';i++) printf("%c",node[i]); puts(""); } else puts(node); } } }