题目链接:https://vjudge.net/problem/51Nod-1282

题目来源: Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
 
有N个时钟,每个时钟有M个指针,P个刻度。时钟是圆形的,P个刻度均分整个圆。每个时钟每个指针指向整数刻度,并且每个时钟自身指针指向的数字都不同。你可以任意旋转时钟的表盘,但是你不能转指针。问最后有多少对时钟可以变成相同的状态。
例如:N = 5,M = 2,P = 4,5个时钟的数据如下{1, 2} {2, 4} {4, 3} {2, 3} {1, 3}
经过旋转后。 其中(1, 3), (1, 4), (2, 5) 和 (3, 4)是相同的。
给出所有时钟的数据,求有多少对时钟是相同的。
Input
第1行:3个数N, M, P中间用空格分隔,其中N为时钟的数量,M为表针的数量,P为刻度的数量(1 <= M, N <= 500, 1 <= P <= 10^9, M <= P)。
第2 - N + 1行:每行M个数,对应一个时钟,M个指针的位置。
Output
输出有多少对时钟是相同的。
Input示例
5 2 4
1 2
2 4
4 3
2 3
1 3
Output示例
4

题解:

1.对于每个时钟,计算所有相邻时针的间隔,然后用最小表示法表示。

2.借助字符串哈希,将每个经过最小表示法处理后的时钟压缩成一个unsigne long long类型的数。

3.使用map维护。

代码如下:

 #include <bits/stdc++.h>
#define rep(i,a,n) for(int (i) = a; (i)<=(n); (i)++)
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; int a[maxn][maxn];
int n,m,p;
map<unsigned long long, int >mp;
const unsigned long long seed = ; int getmin(int *s, int len) //返回最小表示法的始端
{
int i = , j = , k = ;
while(i<len && j<len && k<len)
{
int t = s[(i+k)%len]-s[(j+k)%len];
if (!t) k++;
else
{
if (t>) i += k+;
else j += k+;
if (i==j) j++;
k = ;
}
}
return i<j?i:j;
} int main()
{
int ans = ;
cin>>n>>m>>p;
for(int i = ; i<n; i++)
{
for(int j = ; j<m; j++)
cin>>a[i][j]; sort(a[i], a[i]+m);
a[i][m] = a[i][]+p;
for(int j = ; j<m; j++) //获得间隔距离
a[i][j] = a[i][j+]-a[i][j]; int k = getmin(a[i], m); //k为始端
unsigned long long s = ;
for(int j = ; j<m; j++)
{
int t = (j+k)%m;
s = 1LL*s*seed + 1LL*a[i][t]; //字符串哈希,seed相当于进制
}
ans += mp[s]; //统计对数
mp[s]++; //加入到map中
}
cout<<ans<<endl;
}

一开始没有用字符串哈希,直接把数组用队列的形式丢进map中,也不会超内存。

 #include <bits/stdc++.h>
#define rep(i,a,n) for(int (i) = a; (i)<=(n); (i)++)
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; int a[maxn][maxn];
int n,m,p;
map< queue<int>, int >mp; //把数组以队列的形式丢进map中 int getmin(int *s, int len)
{
int i = , j = , k = ;
while(i<len && j<len && k<len)
{
int t = s[(i+k)%len]-s[(j+k)%len];
if (!t) k++;
else
{
if (t>) i+=k+;
else j+=k+;
if (i==j) j++;
k=;
}
}
return i<j?i:j;
} int main()
{
int ans = ;
cin>>n>>m>>p;
for(int i = ; i<n; i++)
{
for(int j = ; j<m; j++)
cin>>a[i][j]; sort(a[i], a[i]+m);
a[i][m] = a[i][]+p;
for(int j = ; j<m; j++)
a[i][j] = a[i][j+]-a[i][j]; int k = getmin(a[i], m);
queue<int>v;
for(int j = ; j<m; j++)
{
int t = (j+k)%m;
v.push(a[i][t]);
}
ans += mp[v];
mp[v]++;
}
cout<<ans<<endl;
}

51Nod 1282 时钟 —— 最小表示法 + 字符串哈希的更多相关文章

  1. 1282 时钟(最小表示法+hash)

    1282 时钟 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有N个时钟,每个时钟有M个指针,P个刻度.时钟是圆形的,P个刻度均分整 ...

  2. 51nod 1282 时钟

    1282 时钟  题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有N个时钟,每个时钟有M个指针,P个刻度.时钟是圆形的,P个刻度均分 ...

  3. 【字符串】【最小表示法】Vijos P1683 有根树的同构问题

    题目链接: https://vijos.org/p/1683 题目大意: 给M棵树,每棵N个点,N-1条边,树边有向,问哪些树同构. 题目思路: [字符串][最小表示法] 用()表示一个节点,那么三个 ...

  4. HDU 4162 Shape Number(字符串,最小表示法)

    HDU 4162 题意: 给一个数字串(length <= 300,000),数字由0~7构成,求出一阶差分码,然后输出与该差分码循环同构的最小字典序差分码. 思路: 第一步是将差分码求出:s[ ...

  5. BZOJ1398: Vijos1382寻找主人 Necklace 字符串最小表示法

    Description 给定两个项链的表示,判断他们是否可能是一条项链. Input 输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的). Output 如果 ...

  6. HDU——2609How many(字符串的最小表示法+substr)

    How many Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  7. POJ 1509 Glass Beads【字符串最小表示法】

    题目链接: http://poj.org/problem?id=1509 题意: 求循环字符串的最小表示. 分析: 浅析"最小表示法"思想在字符串循环同构问题中的应用 判断两字符串 ...

  8. 牛客练习赛36 A Rabbit的字符串(字符串最小表示法)

    链接:https://ac.nowcoder.com/acm/contest/328/A来源:牛客网 题目描述 Rabbit得到了一个字符串,她的好朋友xxx可以给这个字符串施加一次魔法. 魔法可以选 ...

  9. bzoj2176 Strange string(字符串最小表示法)

    Time Limit: 10 Sec  Memory Limit: 259 MB 给定一个字符串S = {S1, S2, S3 … Sn}, 如果在串SS中, 子串T(|T| = n)为所有长度为n的 ...

随机推荐

  1. Spring Open Session In View

    提出:session在应用层就关闭,所以持久化要在应用层,但是到了view层持久化则session已经关闭 解决:session延迟到view层再关闭 原理:session(整个requestScop ...

  2. Java中的自动类型转换

    Java里所有的数值型变量可以进行类型转换,这个大家都知道,应该不需要详细解释为什么. 2 在说明自动类型转换之前必须理解这样一个原则“表数范围小的可以向表数范围大的进行自动类型转换” 3 关于jav ...

  3. 【SPOJ220】Relevant Phrases of Annihilation(后缀数组,二分)

    题意: n<=10,len<=1e4 思路: #include<cstdio> #include<cstring> #include<string> # ...

  4. java多线程02-----------------synchronized底层实现及JVM对synchronized的优化

    java多线程02-----------------synchronized底层实现及JVM对synchronized的优化 提到java多线程,我们首先想到的就是synchronized关键字,它在 ...

  5. Spring中使用byName实现Beans自动装配

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/beans-auto-wiring/spring-autowiring-byname.html: 此 ...

  6. Docker 基础底层架构浅谈

    docker学习过程中,免不了需要学习下docker的底层技术,今天我们来记录下docker的底层架构吧! 从上图我们可以看到,docker依赖于linux内核的三个基本技术:namespaces.C ...

  7. Docker 的CMD与ENTRYPOINT区别

    我们在构建一个docker镜像的时候,Dockerfile里面有两个命令会引起我们的注意,它们就是 CMD 和 ENTRYPOINT,看起来很相似,实际上并非如此. 一.CMD 顾名思义就是允许用户指 ...

  8. Application具体解释(一)

     1:Application是什么? Application和Activity,Service一样,是android框架的一个系统组件.当android程序启动时系统会创建一个 applicati ...

  9. [Rust] Pass a JavaScript Function to WebAssembly and Invoke it from Rust

    In some cases it’s useful to be able to invoke a JavaScript function inside Rust. This session showc ...

  10. EBS OAF开发中怎样实现功能页签(Global Tab)

    EBS OAF开发中怎样实现功能页签(Global Tab) (版权声明.本人原创或者翻译的文章如需转载.如转载用于个人学习,请注明出处.否则请与本人联系,违者必究) 功能页签的实现不须要不论什么编码 ...