[JSOI2009]电子字典 hash
题面:洛谷
题解:
做法。。。。非常暴力。
因为要求的编辑距离最多只有1,所以我们直接枚举对那个位置(字符)进行操作,进行什么样的操作,加入/修改/删除哪个字符,然后暴力枚举hash判断即可,
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define R register int 4 #define AC 25 5 #define ac 10100 6 #define base 26 7 #define LL long long 8 #define us unsigned 9 10 int n, m, len, ans, cnt, dfn; 11 int id[ac]; 12 us LL hs[ac], qw[AC], ls[AC], rs[AC]; 13 char s[AC]; 14 15 void build() 16 { 17 scanf("%s", s + 1), len = strlen(s + 1), ++ cnt; 18 for(R i = 1; i <= len; i ++) hs[cnt] = hs[cnt] * base + s[i]; 19 } 20 21 void pre() 22 { 23 scanf("%d%d", &n, &m); 24 for(R i = 1; i <= n; i ++) build(); 25 sort(hs + 1, hs + n + 1); 26 qw[0] = 1; 27 for(R i = 1; i <= 20; i ++) qw[i] = qw[i - 1] * base; 28 } 29 30 bool half(us LL x) 31 { 32 int l = 1, r = n, mid; 33 while(l < r) 34 { 35 mid = (l + r) >> 1; 36 if(hs[mid] == x) 37 { 38 if(id[mid] == dfn) return false; 39 id[mid] = dfn; return true; 40 } 41 else if(hs[mid] < x) l = mid + 1; 42 else r = mid - 1; 43 } 44 if(hs[l] != x) return false; 45 if(id[l] == dfn) return false; 46 id[l] = dfn; return true; 47 } 48 49 bool check() 50 { 51 scanf("%s", s + 1), len = strlen(s + 1), ans = 0, ++ dfn; 52 us LL x = 0; 53 memset(rs, 0, sizeof(rs));//why?????大概是因为下面判断的时候可能用到r[len + 1]吧,而r[len + 1]应该要=0的 54 for(R i = 1; i <= len; i ++) x = x * base + s[i]; 55 if(half(x)) 56 { 57 printf("-1\n"); 58 return true; 59 } 60 for(R i = 1; i <= len; i ++) ls[i] = ls[i - 1] * base + s[i]; 61 for(R i = 1; i <= len; i ++) rs[i] = ls[len] - ls[i - 1] * qw[len - i + 1]; 62 //for(R i = 1; i <= len; i ++) printf("%lld ", rs[i]); 63 //printf("\n"); 64 return false; 65 } 66 67 void get() 68 { 69 us LL x; 70 for(R i = 0; i <= len; i ++)//枚举对哪一位进行操作, 71 {//如果是插入的话就是在这个位置的后面插入 72 if(i)//只有i > 0才可以删除和修改 73 { 74 for(R j = 0; j < 26; j ++)//枚举修改成哪个 75 { 76 x = ls[i - 1] * qw[len - i + 1] + 1LL * (j + 'a') * qw[len - i] + rs[i + 1]; 77 if(half(x)) ans ++; 78 } 79 x = ls[i - 1] * qw[len - i] + rs[i + 1]; 80 if(half(x)) ans ++; 81 } 82 for(R j = 0; j < 26; j ++)//枚举在后面插入哪个 83 { 84 x = ls[i] * qw[len - i + 1] + 1LL * (j + 'a') * qw[len - i] + rs[i + 1]; 85 if(half(x)) ans ++; 86 } 87 } 88 printf("%d\n", ans); 89 } 90 91 void work() 92 { 93 for(R i = 1; i <= m; i ++) 94 { 95 if(check()) continue; 96 get(); 97 } 98 } 99 100 int main() 101 { 102 // freopen("in.in", "r", stdin); 103 pre(); 104 work(); 105 // fclose(stdin); 106 return 0; 107 }