hdu 2428 哈希 2008成都
题意: 平面上有1000个点,给出了每个点的坐标,每个点的坐标值都是整数,现在求出这个平面内有多少个正方形,要求这些正方形的边都是平行坐标轴的。
思路: 首先想到的就是对坐标值离散化,但是离散化后出现的问题就是距离表示会出现问题。 可以用一个反函数解决这个问题。 首先让横坐标相同的点弄在一个集合里,然后枚举一个集合里的两个点,那么由这个两个点确定的正方形就确定了(规定一个找的方向)。然后看另外两个点存在不存在。这里找的时候就用到了一个反函数。这里学会了对vector排序。
AC代码:
View Code
#include <iostream> #include <cstring> #include <cstdio> #include <string> #include <algorithm> #include <map> #include <vector> using namespace std; const int N = 2005; struct pp { int x, y; friend bool operator < (pp A, pp B) { if(A.x != B.x) { return A.x < B.x; } else return A.y < B.y; } } p[N]; bool mp[N][N]; int n, a[N], hash[N]; vector<pp>v[N]; map<int,int>g; void init() { int tp = 0; for(int i=1; i<=n; i++) { scanf("%d%d", &p[i].x, &p[i].y); a[++tp] = p[i].x; a[++tp] = p[i].y; } sort(a+1, a+tp+1); g.clear(); tp = 0; for(int i=1; i<=2*n; i++) { if(g.find(a[i]) == g.end()) { g[a[i]] = ++tp; hash[tp] = a[i]; } v[i].clear(); } memset(mp,0,sizeof(mp)); for(int i=1; i<=n; i++) { p[i].x = g[p[i].x]; p[i].y = g[p[i].y]; v[p[i].x].push_back(p[i]); mp[p[i].x][p[i].y] = 1; } } void solve() { int x1,y1, x2, y2,s,x; int ans = 0; for(int i=1; i<=2*n; ++i) { if(v[i].size() < 2) continue; sort(v[i].begin(),v[i].end()); for(int j=0; j<v[i].size(); j++) { x1 = v[i][j].x; y1 = v[i][j].y; for(int k=j+1; k<v[i].size(); k++) { x2 = v[i][k].x; y2 = v[i][k].y; s = hash[y2] - hash[y1]; x = hash[x1] + s; x = g[x]; if(mp[x][y1] && mp[x][y2]) ans++; } } } printf("%d\n", ans); } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d", &n); init(); solve(); } return 0; }


浙公网安备 33010602011771号