地址 https://www.acwing.com/problem/content/description/139/
有 N 片雪花,每片雪花由六个角组成,每个角都有长度。 第 i 片雪花六个角的长度从某个角开始顺时针依次记为 ai,1,ai,2,…,ai,6。 因为雪花的形状是封闭的环形,所以从任何一个角开始顺时针或逆时针往后记录长度,得到的六元组都代表形状相同的雪花。 例如 ai,1,ai,2,…,ai,6 和 ai,2,ai,3,…,ai,6,ai,1 就是形状相同的雪花。 ai,1,ai,2,…,ai,6 和 ai,6,ai,5,…,ai,1 也是形状相同的雪花。 我们称两片雪花形状相同,当且仅当它们各自从某一角开始顺时针或逆时针记录长度,能得到两个相同的六元组。 求这 N 片雪花中是否存在两片形状相同的雪花。 输入格式 第一行输入一个整数 N,代表雪花的数量。 接下来 N 行,每行描述一片雪花。 每行包含 6 个整数,分别代表雪花的六个角的长度(这六个数即为从雪花的随机一个角顺时针或逆时针记录长度得到)。 同行数值之间,用空格隔开。 输出格式 如果不存在两片形状相同的雪花,则输出: No two snowflakes are alike. 如果存在两片形状相同的雪花,则输出: Twin snowflakes found. 数据范围 1≤N≤100000, 0≤ai,j<10000000 输入样例: 2 1 2 3 4 5 6 4 3 2 1 6 5 输出样例: Twin snowflakes found.
解答 使用哈希记录每个雪花的特征 便于比对相同雪花
关键在于选择合适的哈希函数
这里使用的是 将6片雪花的值的积与和相加 再%一个质数,这样相同6片雪花的值必然会得出同一个结果,然后我们再进行比对
// 21342343254.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <stdio.h> #include <map> #include <vector> #include <memory.h> using namespace std; /* 输出格式 如果不存在两片形状相同的雪花,则输出: No two snowflakes are alike. 如果存在两片形状相同的雪花,则输出: Twin snowflakes found. 数据范围 1≤N≤100000, 0≤ai,j<10000000 输入样例: 2 1 2 3 4 5 6 4 3 2 1 6 5 输出样例: Twin snowflakes found. 难度:简单 时/空限制:1s / 64MB 总通过数:1688 总尝试数:5413 来源:《算法竞赛进阶指南》 算法标签 */ int n; //map<long long, vector<int> > mm; int mm[100015][6]; int p = 1e5+13; int GetHash(const int arr[6]) { long long ret = 1; for (int i = 0; i < 6; i++) { ret *= arr[i]; ret %=p; } for (int i = 0; i < 6; i++) { ret += arr[i]; ret %=p; } return ret; } bool check(const int a[6], const int b[6]) //判断两片雪花是否相同 { for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) { bool flag = 1; for (int k = 0; k < 6; k++) //两个雪花方向上相同和相反都判一遍 if (a[(i + k) % 6] != b[(j + k) % 6]) flag = 0; if (flag) return 1; flag = 1; for (int k = 0; k < 6; k++) if (a[(i + k) % 6] != b[(j - k + 6) % 6]) flag = 0; if (flag) return 1; } return 0; } int main() { scanf("%d",&n); int arr[6]; memset(mm,-1,sizeof mm); for (int i = 0; i < n; i++) { for (int j = 0; j < 6; j++) { scanf("%d",&arr[j]); } int hashV = GetHash(arr); if (mm[hashV][0] != -1) { if (check(mm[hashV], arr) == 1) { cout << "Twin snowflakes found." << endl; return 0; } } memcpy(mm[hashV] , arr, sizeof(arr[0])*6); } cout << "No two snowflakes are alike." << endl; return 0; }
我的视频题解空间