题意:

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. 新蜂商城的mybatis plus版本,添加了秒杀专区、优惠卷领取以及后台搜索功能

    本项目是在newbee-mall项目的基础上改造而来,将orm层由mybatis替换为mybatis-plus,添加了秒杀功能.优惠劵功能以及后台搜索功能,喜欢的话麻烦给我个star 后台管理模块添加 ...

  2. 【MyBatis】MyBatis CRUD

    MyBtis CRUD 文章源码 基于代理 DAO 的 CRUD 根据 ID 查询操作 在持久层接口中添加 findById 方法: public interface UserDAO { /** * ...

  3. 【C++】《Effective C++》第一章

    第一章 让自己习惯C++ C++是一个威力强大的语言,带着众多特性,但是在你可以驾驭其威力并有效运用其特性之前,你必须先习惯C++的办事方式. 条款01:视C++为一个语言联邦 如今的C++已经是个多 ...

  4. 【Oracle】11g direct path read介绍:10949 event、_small_table_threshold与_serial_direct_read

    转自刘相兵老师的博文: http://www.askmaclean.com/archives/11g-direct-path-read-10949-_small_table_threshold-_se ...

  5. 关于cin, cin.get(), getchar(),getline()的字符问题

    一.getchar()和cin.get() getchar()会将开头的空格或者回车作为输入 1 #include<iostream> 2 using namespace std; 3 i ...

  6. 【MYSQL】DDL语句

    介绍:DDL语句,即数据定义语句,定义了不同的数据段,数据库表.表.列.索引等数据库对象:例如,create.drop.alter 适用对象:一般是由数据库管理员DBA使用 1.连接数据库 mysql ...

  7. Android N selectQualifiedNetwork分析

    前言: 参考:Android N wifi auto connect流程分析 后续 Android 8.0/9.0 wifi 自动连接评分机制 分析 前面说了,handleScanResults会去调 ...

  8. Shell从入门到精通

    熟悉基本shell操作不仅是运维的基本功,对于开发来说也是多多益善,我在学习的过程中,总结了十个练手的小demo,并附上涉及的知识点,仅供娱乐. 1. 多线程ping监控,检查同一网段的IP是否连通 ...

  9. JAVA SSM整合流程以及注意点

    1.搭建整合环境 整合说明:SSM整合可以使用多种方式,咱们会选择XML + 注解的方式 先搭建整合的环境 先把Spring的配置搭建完成 再使用Spring整合SpringMVC框架 最后使用Spr ...

  10. SpringBoot+Spring常用注解总结

    为什么要写这篇文章? 最近看到网上有一篇关于 SpringBoot 常用注解的文章被转载的比较多,我看了文章内容之后属实觉得质量有点低,并且有点会误导没有太多实际使用经验的人(这些人又占据了大多数). ...