题意:

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. RabbitMQ常用的几种消息模型

    第一种模型(HelloWorld) 上图来自官方文档 P代表生产者用来生产消息,发送给消费者C,中间的共色部分代表消息队列,用来缓存消息. 首先导入依赖 <dependency> < ...

  2. 一道有趣的golang排错题

    很久没写博客了,不得不说go语言爱好者周刊是个宝贝,本来想随便看看打发时间的,没想到一下子给了我久违的灵感. go语言爱好者周刊78期出了一道非常有意思的题目. 我们来看看题目.先给出如下的代码: p ...

  3. linux之curl工具

    curl是一个利用URL语法在命令行下工作的文件传输工具,作用是发出网络请求,然后获取数据:它支持文件的上传和下载:支持多种通信协议. 一.查看网页源码 直接在 curl 命令后加上网址,默认会发送 ...

  4. cursor pin s和cursor pin s wait on x

    1.cursor pin s是一个共享锁,一般情况下是因为发生在SQL短时间内大量执行 案例:在生产库中,突然出现大量的cursor pin s的等待,询问是否有动作后,同事说有编译存储过程(被误导了 ...

  5. C++:I/O流的概念和流类库的结构

    一.C++输入输出包含以下三个方面的内容: 对系统指定的标准设备的输入和输出.即从键盘输入数据,输出到显示器屏幕.这种输入输出称为标准的输入输出,简称标准I/O. 以外存磁盘文件为对象进行输入和输出, ...

  6. CMU数据库(15-445)Lab1-BufferPoolManager

    0. 关于环境搭建请看 https://www.cnblogs.com/JayL-zxl/p/14307260.html 1. Task1 LRU REPLACEMENT POLICY 0. 任务描述 ...

  7. apscheduler(定时任务) 基于redis持久化配置操作

    apscheduler(定时任务) 基于redis持久化配置操作 安装模块 pip install apscheduler 导入模块配置 ## 配置redis模块 from apscheduler.j ...

  8. C#+Layui开发后台管理系统

    ​我是笑林新记,分享一下我一套C#开发的后台管理系统,希望对大家有帮助!欢迎关注微信公众号:笑林新记   后台开发语言:C# 前端框架:layui   前天用毛笔笔画制作了一个毛笔字效果的Logo,主 ...

  9. (16)-Python3之--集合(set)操作

    1.定义 集合的关键字:set 集合主要作用: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 集合用大括号{}表示,元素间用逗号分隔. 建立集合类型用{} ...

  10. postgres多知识点综合案例

    使用到的知识点: 1.使用with临时存储sql语句,格式[with as xxx(), as xxx2() ]以减少代码: 2.使用round()取小数点后几位: 3.使用to_char()将时间格 ...