题意:

t组输入,每组数据输入一个整数n,代表字符串长度。下面再输入一个字符串

你需要判断这个字符串能不能分成大于1段,且这些段的最小表示法是一样的

例如:abccab,它可以分成2段,分别是abc和cab,它们都使用最小表示法(也就是字典序最小表示)表示之后都是abc,所以这两个串一样

题解:

因为你需要把字符串分成若干段,假设分成x段,那么x肯定满足n%x==0

这里就有两种方法,第一种就是枚举n的因子,然后再暴力去判断这个因子可不可以

另一种就是:假如存在一个可以满足题意的因子x(也就是说一段的长度为x,且每一段都相等),那么分成n/x段,每一段里面每一个字母的个数肯定要保持一样多

那么我们可以去找所有字母个数的最大公因子,设为ans,然后在1-ans里面暴力枚举就行。这样比去暴力枚举n的因子复杂度小

我们如何判断一个因子x可以不可满足题意?

对于一个串abccab,我们可以得出来a、b、c字母得个数都是2,那么它们和n的最大公因数就是2

那么长度为n的串,最多分成2段,每一段的长度n/2

然后我们开始暴力枚举[1,2)这个区间的因子,首先要判断一下n%x==0,不等于0这个因子就不行

这个枚举的是将几个n/2合并,例如1是满足n%x==0

这个时候abc为一段,cab为一段(如果x==2,那么就是将2个n/2合并成一段,即abccab为一段,因为题目要求必须将字符串分开,所以2不可以)

对于第一段abc,我们先标记一下abc的哈希值,然后再标记一下bca的哈希值,再标记cab的哈希值

然后再去判断后面的段的哈希值是否被标记过,如果标记过就没事,没标记过就证明这个因子不行

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<map>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int blo=13331;
const int maxn = 5e6+5;
ll xp[maxn],hash_1[maxn],num[maxn];
map<ll,ll>r;
void init()
{
xp[0]=1;
for(ll i=1; i<maxn; i++)
xp[i]=xp[i-1]*blo;
}
ll make_hash(char str[],ll hash_[],ll len)
{
hash_[0]=0;
for(ll i=1; i<=len; i++)
{
hash_[i]=hash_[i-1]*blo+(str[i]-'a'+1);
//cout<<hash_[i]<<" ";
}
return len;
}
char str[maxn];
int main()
{ init();
ll t;
scanf("%lld",&t);
while(t--)
{
//r.clear();
ll n,flag=1;
scanf("%lld",&n);
scanf("%s",str+1);
make_hash(str,hash_1,n);
memset(num,0,sizeof(num));
for(ll i=1;i<=n;++i)
{
num[str[i]-96]++;
}
ll ans=n;
for(ll i=1;i<=26;++i) //如果分组之后每组字符串最小表示法都一样,那么里面的每个字母的数量也一样,所以我们可以
{ //以此来下手
if(num[i])
ans=__gcd(ans,num[i]); //这个ans里面放的就是最多你能分成多少组
}
ll u=n/ans; //按照最大分成ans组,每一组的长度
if(u==1 && n!=1)
{
flag=0;
}
else
{
for(ll k=1;k<ans;++k) //枚举判断
{
ll len=k*u;
if(n%len)
{
continue;
}
r.clear();
flag=0;
ll temp=hash_1[len]-hash_1[0]*xp[len];
r[temp]=1;
for(ll i=1;i<=len;++i) //将一个字符串的各种类型字符串哈希值都算出来,并标记
{ //例如字符串abc,你不仅要算出来abc的哈希值,还要算出来bca、cab的哈希值
temp=temp*blo+(str[i]-96);
r[temp-hash_1[i]*xp[len]]=1;
}
for(ll j = 1; j * len <= n; j++) //判断后面几组是否和第一组一样
{ if(r[hash_1[j*len]-hash_1[(j - 1)*len]*xp[len]]==0)
{
flag = 1;
break;
}
}
if (flag == 0)
{ break;
}
}
}
if(!flag)
printf("Yes\n");
else printf("No\n");
}
return 0;
}

hdu 6863 Isomorphic Strings 哈希+求公因子的更多相关文章

  1. leetcode 205. Isomorphic Strings(哈希表)

    Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...

  2. [LeetCode] Isomorphic Strings

    Isomorphic Strings Total Accepted: 30898 Total Submissions: 120944 Difficulty: Easy Given two string ...

  3. Codeforces 985 F - Isomorphic Strings

    F - Isomorphic Strings 思路:字符串hash 对于每一个字母单独hash 对于一段区间,求出每个字母的hash值,然后排序,如果能匹配上,就说明在这段区间存在字母间的一一映射 代 ...

  4. Educational Codeforces Round 44 (Rated for Div. 2) F - Isomorphic Strings

    F - Isomorphic Strings 题目大意:给你一个长度为n 由小写字母组成的字符串,有m个询问, 每个询问给你两个区间, 问你xi,yi能不能形成映射关系. 思路:这个题意好难懂啊... ...

  5. leetcode:Isomorphic Strings

    Isomorphic Strings Given two strings s and t, determine if they are isomorphic. Two strings are isom ...

  6. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...

  7. [leetcode]205. Isomorphic Strings 同构字符串

    Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...

  8. CodeForces985F -- Isomorphic Strings

    F. Isomorphic Strings time limit per test 3 seconds memory limit per test 256 megabytes input standa ...

  9. LeetCode 205. 同构字符串(Isomorphic Strings)

    205. 同构字符串 205. Isomorphic Strings

随机推荐

  1. Linux Bash Shell常用快捷键

    Linux Bash Shell常用快捷键 table { margin: auto } 快捷键 功能 tab 补全 ctrl + a 光标回到命令行首 ctrl + e 光标回到命令行尾 ctrl ...

  2. Linux学习笔记 | 常见错误之VMware启动linux后一直黑屏

    方法1: 宿主机(windows)管理员模式运行cmd 输入netsh winsock reset 然后重启电脑 netsh winsock reset命令,作用是重置 Winsock 目录.如果一台 ...

  3. apiAutoTest: 接口自动化测试的数据清洗(备份/恢复)处理方案

    接口自动化测试之数据清洗/隔离/备份/恢复 在得到QQ:1301559180 得代码贡献之后,想到了通过ssh连接上服务器,然后进行数据库备份,数据库恢复, 主要使用了 paramiko库 最终效果 ...

  4. Linux内核分析_课程学习总结报告

    请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的.自洽的,并举例某一两个具体例子(比如读写文件.分配内存.使用I/O ...

  5. 微服务网关2-搭建Gateway服务

    一.创建父模块infrastructure 1.创建模块 在guli_parent下创建普通maven模块 Artifact:infrastructure 2.删除src目录 二.创建模块api_ga ...

  6. .NET Core使用Source Link提高源代码调试体验和生产效率

    前言: 在我们日常开发过程中常常会使用到很多其他封装好的第三方中间件(NuGet依赖项).类库或者是.NET框架中自带的库.但是当你想要对这些类库的方法设置断点调试,然后发现无法F11(逐语句)调试进 ...

  7. InnoDB的主键选择与插入优化

    索引的存放方式MyISAM和InnoDB存储引擎在MySQL中,不同存储引擎对索引的实现方式是不同的,总结下MyISAM和InnoDB两个存储引擎的索引实现方式.MyISAM引擎使用B+Tree作为索 ...

  8. 相对论中的光速c不变,这么讲!你总能理解了吧!

    今天谈谈相对论的假设基础--光速不变,很多人都知道爱因斯坦的相对论,也知道相对论的理论基础是光速不变,即无论参考哪个参照系,光的速度都是不变的,这个很难得理解的问题.我之前看过别人的理解,也自己思考怎 ...

  9.  Go is more about software engineering than programming language research.

    https://talks.golang.org/2012/splash.article Go at Google: Language Design in the Service of Softwar ...

  10. go mod 以及vscode解决被墙的插件问题

    https://blog.csdn.net/weixin_39003229/article/details/97638573?utm_medium=distribute.pc_relevant.non ...