51Nod-1282-时钟
来源:互联网 发布:手机故障检测软件 编辑:程序博客网 时间:2024/05/24 00:56
ACM模版
描述
题解
先将指针排序,然后获取指针刻度差值,接着,找到一个起点存储起来,用作后续的比较。这里起点的查找标准具体看函数,不做解释。求得有多少段相同的序列,累加相同状态的钟表对儿数即可(代码One)。
这里可以进行一个比较好的优化,使用哈希+map(代码Two)。
代码
One:
#include <iostream>#include <algorithm>#include <cstdio>using namespace std;const int MAXN = 5e3 + 5;const int INF = 0x3f3f3f3f;int N, M, P;int hands[MAXN];int hand[MAXN];struct clo{ int hands[MAXN];} Clock[MAXN];bool cmp(clo a, clo b){ for (int i = 0; i < M; i++) { if (a.hands[i] != b.hands[i]) { return a.hands[i] < b.hands[i]; } } return false;}// 检测是否相等bool cmp_(clo a, clo b){ for (int i = 0; i < M; i++) { if (a.hands[i] != b.hands[i]) { return false; } } return true;}void squ(int key, int *hand){ int MIN = INF; int pos = 0; for (int i = 0; i < M; i++) { if (hand[i] < MIN) { MIN = hand[i]; pos = i; } } for (int i = pos + 1; i < M; i++) { if (hand[i] == hand[pos]) { for (int j = 1; j < M; j++) { if (hand[(i + j) % M] > hand[(pos + j) % M]) { break; } else if (hand[(i + j) % M] < hand[(pos + j) % M]) { pos = i; } } } } int tag = 0; for (int i = pos; i < M; i++) { Clock[key].hands[tag++] = hand[i]; } for (int i = 0; i < pos; i++) { Clock[key].hands[tag++] = hand[i]; } return ;}int main(int argc, const char * argv[]){ cin >> N >> M >> P; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { scanf("%d", hands + j); } sort(hands, hands + M); hand[0] = P - hands[M - 1] + hands[0]; for (int j = 1; j < M; j++) { hand[j] = hands[j] - hands[j - 1]; }// sort(Clock[i].hands, Clock[i].hands + M); // WA,需要按特殊规则排 squ(i, hand); } sort(Clock, Clock + N, cmp); int pos = 0; int ans = 0; for (int i = 1; i <= N; i++) { if (!cmp_(Clock[pos], Clock[i])) { int num = i - pos; ans += num * (num - 1) / 2; pos = i; } } std::cout << ans << '\n'; return 0;}
Two:
#include <iostream>#include <algorithm>#include <map>#include <cstdio>using namespace std;const int N = 500 + 10;int n, m, p;int A[N][N], B[N][N];int minID[N];void input(){ for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { scanf("%d", &A[i][j]); } } for (int i = 0; i < n; ++i) { sort(A[i], A[i] + m); // 求指针差 for (int j = 0; j < m; ++j) { B[i][j] = (A[i][(j + 1) % m] - A[i][j] + p ) % p; } }}// 寻找起点int getMin(int *C){ int i = 0, j = 1, k = 0; while (i < m && j < m && k < m) { int t = C[(i + k) % m] - C[(j + k) % m]; 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;}map<int, int> S;int SEED = 133331;void solve(){ for (int i = 0; i < n; ++i) { minID[i] = getMin(B[i]); } S.clear(); int ans = 0; for (int i = 0; i < n; ++i) { int tmp = 1; for (int k = 0; k < m; ++k) { tmp = tmp * SEED + B[i][(minID[i] + k) % m]; // 哈希 } ans += S[tmp]; S[tmp]++; } cout << ans << endl; return ;}int main(){ while (~scanf("%d%d%d", &n, &m, &p)) { input(); solve(); } return 0;}
0 0
- 51Nod-1282-时钟
- 51nod 1282 时钟
- 51NOD 1282 时钟
- 51nod 1282 时钟(哈希+最小表示法)
- 51nod 1282 时钟 哈希+最小表示法+map
- 51Nod 1282 时钟 —— 最小表示法 + 字符串哈希
- 51Nod-1005-大数加法
- 51Nod-1011-最大公约数GCD
- 51Nod-1012-最小公倍数LCM
- 51Nod-1018-排序
- 51Nod-1019-逆序数
- 51Nod-1027-大数乘法
- 51Nod-1066-Bash游戏
- 51Nod-1069-Nim游戏
- 51Nod-1072-威佐夫游戏
- 51Nod-1073-约瑟夫环
- 51Nod-1085-背包问题
- 51Nod-1106-质数检测
- ANSYS使用笔记(一):开始使用
- Leetcode 196. Delete Duplicate Emails
- js 声明数组和向数组中添加对象变量
- Leetcode 197. Rising Temperature
- JavaScript深入浅出(一)数据类型
- 51Nod-1282-时钟
- JavaScript数组和循环
- TortoiseGit状态图标不正常或不显示的问题修复
- 大数据成果(发展和未来)
- 树形dp(Centroids,cf 708C)
- Python常见数据结构整理
- 关系数据库的第一第二第三范式
- 机器学习部分国内牛人
- 开博第一篇