哈希函数把一个只由小写字符组成的字符串转化成了一个26进制的数,不取模的情况下,任意小写字符串和自然数是一一对应的。因此,只要把给的字符串转换成对应的26进制整数,加上模数后转换回字符串,一定可以得到一个最小字典序大于原串的字符串。只要这个新字符串长度为6即是满足要求的字符串。
加mod还不行 说明越zzzzzz的界了 即长度大于6 加k*mod就更不行了
mod比最大hash值266-1小 所以有可能加上mod后还在长度为6的字符串hash值范围内
mod比最大hash值266-1小 所以有可能加上mod后还在长度为6的字符串hash值范围内
#include<bits/stdc++.h> using namespace std; char s[10],t[10]; int main(){ int mod; while(~scanf("%s",s)){ scanf("%d",&mod); int has=0; for(int i=0;i<6;i++)has=has*26+s[i]-'a'; has+=mod; for(int i=5;i>=0;i--){ s[i]=has%26+97; has/=26; } s[6]=0; if(has)cout<<-1<<endl; else cout<<s<<endl; } }
刚开始写的搜索 由于多组数据(1000组)妥妥的T
后来想到大于s且取模后hash值等于s的字符串原hash值为hash(s)+k*mod
只需预处理出所有长度为6的字符串的hash值
但3e8预处理还是T了
虽然k从小到大枚举,第一个满足条件的字符串显然字典序最小
由于预处理超时就没继续想下去了 枚举之后只需判断是否在长度为6的字符串的hash值范围内
那么mod不行,即超出了长度为6的字符串hash值范围 k*mod显然也不行
故字符串在26进制下,比较字典序大小等价于比较对应的26进制大小。加mod,取模结果不变同时字典序最小
#include<bits/stdc++.h> using namespace std; char s[10],tmp[10]; int mod,flag,ans=0; int has(char* s){ int res=0; for(int i=0;i<6;i++) res=(1ll*res*26+s[i]-'a')%mod; return res; } void dfs(int step){ if(flag)return; if(step==6){ if(has(tmp)==ans){ flag=1; for(int i=0;i<6;i++)putchar(tmp[i]); return; } return ; } for(char i='a';i<='z';i++){ if(flag)return; tmp[step]=i; dfs(step+1); } } int main(){ while(~scanf("%s",s)){ scanf("%d",&mod); ans=has(s); //cout<<ans<<endl; flag=0; for(int i=5;i>=0;i--){ if(flag)break; strncpy(tmp,s,i); for(char j=s[i]+1;j<='z';j++){ if(flag)break; tmp[i]=j; dfs(i+1); } } if(!flag)cout<<-1<<endl; } return 0; }