哈希表 fzu 1961
Problem 1961 凯撒密码II
Accept: 242 Submit: 614 Time Limit: 2000 mSec Memory Limit : 32768 KB
Problem Description
在人类历史上,对信息保护的需求与对信息本身的需求一样久远。第一个用于加密和解密文本的编码方式是凯撒密码。由于原始的凯撒密码较简单,较易被破解。随着考古的进展,人们发现了升级版的凯撒密码II。
凯撒密码II通过查询动态密码表,把凯撒单词加密成一些密文数字。
现在请你使用现有动态密码表,加密一些单词。你要处理m个操作,操作分成两种:
A string integer: 增加一条凯撒单词string到凯撒密文数字integer的映射规则,如果先前已经有关于这个string的规则,那么用该规则替换原规则。
Q string: 查询单词string所对应的最新密文数字。
Input
第一行一个整数m(1<= m<=1,000,000),表示有m个操作。
单词仅有长度不超过8位的小写字母组成,单词总数不超过100,000个。
密文数字的范围是[0..1,000,000,000]。
Output
对于每组查询,输出一行,表示根据密码表中的规则,加密后的密文数字,如果在无法在密码表中查找到该单词,输出 -1。
Sample Input
7 A aaab 10 A aaac 20 A aaad 30 Q aaac A aaac 40 Q aaaa Q aaac
Sample Output
20 -1 40
#include <iostream> #include<stdio.h> #include<string.h> using namespace std; #define TABLE_SIZE 200003 struct Node { char key[12]; int value; bool flag; Node () { flag = false; } } table[TABLE_SIZE]; unsigned int BKDRHash(char *key){ unsigned int seed = 131; unsigned int hash = 0; while (*key){ hash = hash * seed + (*key++); } return (hash & 0x7FFFFFFF) % TABLE_SIZE; } void insert(char *key,int value){ //return 1 means OVERWRITE int pos = BKDRHash(key), m = 0,ret=0; while (table[pos].flag ) {//has word if(strcmp(table[pos].key, key) == 0){ ret=1;//key match,OVER_WRITE break; } pos += 2 * (++m) - 1; if (pos >= TABLE_SIZE) pos -= TABLE_SIZE; } if(1!=ret){//over write no need this strcpy (table[pos].key, key); } table[pos].value=value; table[pos].flag = true;//mark that has word } int find(char* key){ int pos = BKDRHash(key), m = 0; while (table[pos].flag) { if (strcmp(table[pos].key, key) == 0) { return table[pos].value; } else { pos += 2 * (++m) - 1; pos = (pos >= TABLE_SIZE ? pos - TABLE_SIZE : pos); } } return -1; } int main() { int n,i,d,x; char a,b[10]; while(scanf("%d",&n)!=EOF) { getchar(); for(i=0;i<n;i++) { a=getchar(); getchar(); if(a=='A') { scanf("%s%d",b,&d); insert(b,d); } if(a=='Q') { scanf("%s",b); x=find(b); printf("%d\n",x); } getchar(); } } return 0; }