Hdu多校8-1009 hdu-6863 Isomorphic Strings
程序员文章站
2023-12-31 15:39:28
...
题目链接:点击跳转
Problem Description
Input
Output
For each test case, output one line containing ‘‘Yes’’ or ‘‘No’’ (without quotes).
Sample Input
6
1
a
2
aa
3
aab
4
abba
6
abcbcc
8
aaaaaaaa
Sample Output
No
Yes
No
Yes
No
Yes
题目大意:求给出的字符串的长度的因子(大于1的),以该因子拆分原串,是否每一串都可以是其他串的循环同构
解题思路:这里用string的substr和find函数来解决的,当然,string的封装方法的效率都相当低,所以需要维护一个前缀和(O(n*26))来优化,因为如果是循环同构,那么每个字符的数量一定是相等的,如果都相等,才需要去比较。找到一个k满足题意就可以退出输出Yes,没有找到则输出No。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
inline void FAST_IO() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
int n;
string s;
int fac[50005],tot,sum[26][5000005];
inline void getFac(){
tot=0;
for(int i=2;i*i<=n;i++){
if(n%i==0)fac[tot++]=i;
if(i*i!=n)fac[tot++]=n/i;
}
fac[tot++]=n;
}
signed main(){
FAST_IO();
int Case;
cin>>Case;
while(Case--){
cin>>n>>s;
if(n==1){
cout<<"No"<<endl;
continue;
}
for(int i=0;i<26;i++)sum[i][0]=0;
sum[s[0]-'a'][0]=1;
for(int i=1;i<n;i++){
for(int j=0;j<26;j++){
sum[j][i]=sum[j][i-1];
}
sum[s[i]-'a'][i]++;
}
getFac();
bool f=false;
for(int i=0;i<tot;i++){
f=true;
int k=n/fac[i];
for(int j=k;j<n;j+=k){
if(!f)break;
for(int l=0;l<26;l++){
if(sum[l][j+k-1]-sum[l][j-1]!=sum[l][k-1]){
f=false;
break;
}
}
}
if(!f)continue;
string str=s.substr(0,k);
str+=str;
for(int j=k;j<n;j+=k){
string str1=s.substr(j,k);
if(str.find(str1)==-1){
f=false;
break;
}
}
if(f)break;
}
if(f){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}
return 0;
}