51nod 1282 时钟(最小表示法,hash)
发布日期:2021-11-02 09:48:39 浏览次数:3 分类:技术文章

本文共 1957 字,大约阅读时间需要 6 分钟。

最小表示法

有一个首位相连的字符串,寻找一个位置,从这个位置向后形成一个新字符串,使这个字符串字典序最小。

// 返回最小表示法的始端int get_min(int *s, int len){
int i = 0, j = 1, k = 0; while (i < len && j < len && k < len) {
int t = s[(i + k) % len] - s[(j + k) % len]; if (!t) k++; else {
if (t > 0) i += k + 1; else j += k + 1; if (i == j) j++; k = 0; } } return i < j ? i : j;}

1282 时钟

题目

有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)是相同的。

在这里插入图片描述

给出所有时钟的数据,求有多少对时钟是相同的。

输入

第1行:3个数N, M, P中间用空格分隔,其中N为时钟的数量,M为表针的数量,P为刻度的数量(1 <= M, N <= 500, 1 <= P <= 109, M <= P)。

第2 - N + 1行:每行M个数,对应一个时钟,M个指针的位置。

输出

输出有多少对时钟是相同的。

输入样例

5 2 4

1 2
2 4
4 3
2 3
1 3

输出样例

4

代码
#include 
using namespace std;#define INF 0x3f3f3f3f#define LL long long#define MX 505const int hash_ = 133331;int n, m, p;int ans;int ke[MX];int cha[MX];map
zz;int get_min(int *s, int len) //返回最小表示法的始端{
int i = 0, j = 1, k = 0; while (i < len && j < len && k < len) {
int t = s[(i + k) % len] - s[(j + k) % len]; if (!t) k++; else {
if (t > 0) i += k + 1; else j += k + 1; if (i == j) j++; k = 0; } } return i < j ? i : j;}void calc() {
sort(ke, ke + m); for (int i = 1; i < m; i++) cha[i - 1] = ke[i] - ke[i - 1]; cha[m - 1] = ke[0] + p - ke[m - 1]; int dex = get_min(cha, m); LL has = 0, quan = 1; for (int i = 0; i < m; i++) {
has += cha[(dex + i) % m] * quan; quan *= hash_; } ans += zz[has]; zz[has]++;}int main() {
scanf("%d%d%d", &n, &m, &p); ans = 0; for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) scanf("%d", &ke[j]); calc(); } printf("%d\n", ans); return 0;}

转载地址:https://blog.csdn.net/weixin_43820352/article/details/108409452 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:51nod 1441 士兵的数字游戏(埃氏筛)
下一篇:51nod 1215 数组的宽度(单调栈)

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月11日 18时00分29秒