HDU 4886 TIANKENG’s restaurant(Ⅱ) 思维+字符串哈希

来源:互联网 发布:淘宝销售直接进销存 编辑:程序博客网 时间:2024/06/07 23:34

传送门:HDU4886

题意:给定字符串,问字符串的子串中没出现过的最短且字典序最小的串是哪个(只能由A-H组成)。

思路:首先要能想到没出现过的串最长可能是多长,这里我们取6或者7都行,因为假如说长度与为6的话,字符串有8^6=262144中情况,如果要这些串都出现的话总串大约就要1500000长度(实际长度肯定比这个少,因为会有首尾重叠的情况,但是就本题而言,可能没有极限数据,长度为6足够了),大于题目给出的长度。

知道了最长长度,然后我们对总串做一个6*n复杂度的哈希,用h[i][j]标记长度为i,哈希值为j的子串出没出现过。最后再扫一遍数组看看最哪个没出现过就输出就好了。

代码:

#include<bits/stdc++.h>#define ll long long#define pb push_back#define fi first#define se second#define pi acos(-1)#define inf 0x3f3f3f3f#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define rep(i,x,n) for(int i=x;i<n;i++)#define per(i,n,x) for(int i=n;i>=x;i--)using namespace std;typedef pair<int,int>P;const int MAXN=100010;int gcd(int a,int b){return b?gcd(b,a%b):a;}bool h[8][3*MAXN];string s;void print(int len,int k){s="";for(int i=0;i<len;i++){s+=((k%8)+'A');k/=8;}reverse(s.begin(),s.end());cout<<s<<endl;}int main(){//cout<<pow(8,6);ios::sync_with_stdio(0);int n;cin>>n;while(n--){memset(h,0,sizeof(h));cin>>s;int sz=s.size();for(int i=0;i<sz;i++){int x=0;for(int j=i;j<i+6&&j<sz;j++){x=x*8+(s[j]-'A');h[j-i+1][x]=1;}}int ed=0,flag=1;for(int i=1;i<=6&&flag;i++){ed+=7*pow(8,i-1);for(int j=0;j<=ed;j++){//print(i,j);if(!h[i][j]){print(i,j);flag=0;break;}}}} return 0;}

原创粉丝点击