
//突然发现好弱,好多基础的算法竟然都不会,哈希这种经典的算法,我貌似基本没怎么做过相关的题0.0
题意:给n个点,问有多少组四个点能组成正方形。
题解:枚举两个点,通过公式算出另外两个点,然后通过哈希查找另外两个点存不存在。
公式是抄网上的,哈希直接用了vector存的,反正时限3500ms
点的哈希就是(x^2+y^2)%MOD
AC代码:
/**************************************
Memory: 924 KB Time: 969 MS
Language: G++ Result: Accepted
**************************************/
#include <cstdio>
#include <cstring>
#include <vector> using namespace std; const int MOD = ;
const int N = ; struct Point {
int x, y;
int key;
} p[N]; int cal(int x, int y) {
return (x*x+y*y) % MOD;
} vector<int> vec[MOD]; void insert(int x) {
vec[p[x].key].push_back(x);
} bool find(int x, int y) {
int k = cal(x, y);
for (unsigned i = ; i < vec[k].size(); ++i) {
int v = vec[k][i];
if (x == p[v].x && y == p[v].y) return true;
}
return false;
} int main() {
//freopen("in", "r", stdin);
int n;
while (~scanf("%d", &n) && n) {
for (int i = ; i < MOD; ++i) vec[i].clear();
for (int i = ; i < n; ++i) {
scanf("%d%d", &p[i].x, &p[i].y);
p[i].key = cal(p[i].x, p[i].y);
insert(i);
}
int ans = ;
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (i == j) continue;
int x1 = p[i].x-p[j].y+p[i].y;
int y1 = p[i].y+p[j].x-p[i].x;
int x2 = p[j].x-p[j].y+p[i].y;
int y2 = p[j].y+p[j].x-p[i].x;
if (find(x1,y1) && find(x2,y2)) ++ans;
}
}
printf("%d\n", ans/);
}
return ;
}
求有没有相同的雪花,每个雪花有12中hash值,分别试一次,插入一个就可以了。时间复杂度O(n*12)。
本来用的上面vector的,然后T了好久T^T
后来改成了类似存图时前向星的方法,3438ms水过去了。
#include <cstdio>
#include <cstring>
#include <vector> using namespace std; const int MOD = ;
const int MAXN = ;
const int N = ; int snow[MAXN][N];
int head[MOD];
int nt[MAXN];
int cnt; void insert(int a[], int x) {
for (int i = ; i < N; ++i) snow[cnt][i] = a[i];
nt[cnt] = head[x];
head[x] = cnt++;
} bool find(int a[], int x) {
//printf("%d %d\n", x, head[x]);
for (int i = head[x]; i != -; i = nt[i]) {
//printf("i=%d\n", i); break;
for (int j = ; j < N; ++j) {
if (a[j] != snow[i][j]) break;
if (j == N-) return true;
}
}
return false;
} int main() {
//freopen("in", "r", stdin);
int n;
while (~scanf("%d", &n) && n) {
cnt = ;
bool fg = false;
memset(head, -, sizeof head);
int a[], b[];
for (int i = ; i < n; ++i) {
for (int i = ; i < N; ++i) scanf("%d", a+i);
if (fg) continue;
int val = ;
for (int i = ; i < N; ++i) {
val = ;
for (int j = ; j < N; ++j) {
val = (val * + a[(i+j)%N]) % MOD;
b[j] = a[(i+j)%N];
}
if (find(b, val)) { fg = true; break; }
val = ;
for (int j = N-; j >= ; --j) {
b[N-j-] = a[(i+j)%N];
val = (val * + a[(i+j)%N]) % MOD;
}
if (find(b, val)) { fg = true; break; }
}
if(!fg) insert(b, val);
}
if (fg) puts("Twin snowflakes found.");
else puts("No two snowflakes are alike."); }
return ;
}