题目大意:
求出在文本串中第一个没出现的字典序最小的串。、
思路分析:
开始的时候 用后缀数组写,然后根据sa的有序性。你就可以知道哪个串没有出现了。
但是题目卡了倍增哦。。。
自习想一想的话,我们用 sa 数组,也就是想知道这个串有没有出现过,也就是判断重复,却浪费了 O (n * lg n)...
判断重复为什么没想到hash 。
把每一个长度的子串都hash 出来,用八进制表示,这样的话就可以得到一个递增的hash值。
将之存入hash 数组。找到第一个空的hash的下标,就是第一个没出现的了,然后分解每一位就得到了答案。这代码 hdu rank 1...(2014 - 07 - 30...)
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; bool hash[1000007]; char str[1000007]; int pow[10]; void print(int x,int dep,int cnt) { if(x) { print(x/8,dep+1,cnt); putchar(x%8+'A'); return; } else if(dep<cnt) { while(dep<cnt) { putchar('A'); dep++; } } } int main() { pow[0]=1; for(int i=1; i<=8; i++)pow[i]=pow[i-1]*8; int T; scanf("%d",&T);getchar(); while(T--) { gets(str); int n=strlen(str); bool found=false; for(int len=1; len<=7; len++) { memset(hash,false,sizeof hash); int init=0; int m=min(len,n); for(int i=0; i<m; i++) { init=str[i]-'A'+init*8; } hash[init]=true; for(int i=len; i<n; i++) { init-=pow[len-1]*(str[i-len]-'A'); init=init*8+str[i]-'A'; hash[init]=true; } for(int i=0; i<pow[len]; i++) { if(!hash[i]) { print(i,0,len); puts(""); found=true; break; } } if(found)break; } } return 0; }
hdu 4886 TIANKENG’s restaurant(Ⅱ) (hash)
时间: 2024-10-23 09:39:05