这是我们理工内部培训册上的一个例题。题目就是给出一组点,问这些点能组成多少个正方形。直接方法便是枚举任意两点,然后根据数学推出另外两点,然后判断这两点是否在点的集合内。立方阶复杂度。 但是可以利用hash来存储各点,hash的目的本来就是实现快速查找,并节省空间。这样的话我们在查找的时候就O1了。求另外两点很好求,但是注意有重复统计。
我这里给出两种形式的hash解决方案:
Squares
我这里给出两种形式的hash解决方案:
Squares
Time Limit: 3500MS | Memory Limit: 65536K | |
Total Submissions: 17694 | Accepted: 6753 |
Description
A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degree angles. It is also a polygon such that rotating about its centre by 90 degrees gives the same polygon. It is not the only polygon with the latter property, however, as a regular octagon also has this property.
So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its x and y coordinates.
So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its x and y coordinates.
Input
The input consists of a number of test cases. Each test case starts with the integer n (1 <= n <= 1000) indicating the number of points to follow. Each of the next n lines specify the x and y coordinates (two integers) of each point. You may assume that the points are distinct and the magnitudes of the coordinates are less than 20000. The input is terminated when n = 0.
Output
For each test case, print on a line the number of squares one can form from the given stars.
Sample Input
4 1 0 0 1 1 1 0 0 9 0 0 1 0 2 0 0 2 1 2 2 2 0 1 1 1 2 1 4 -2 5 3 7 0 0 5 2 0
Sample Output
1 6 1
Source
Rocky Mountain 2004
AC:
AC:
/*=============================================================================
#
# Author: liangshu - cbam
#
# QQ : 756029571
#
# School : 哈尔滨理工大学
#
# Last modified: 2015-08-26 18:28
#
# Filename: E.cpp
#
# Description:
# The people who are crazy enough to think they can change the world, are the ones who do !
=============================================================================*/
#
#include<iostream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cctype>
#include<string>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
const int M = 1007;
int a, b;
struct Point{
int x, y;
Point *next;
}p[1023];
Point *pnd[1034];
struct Node{
int x, y;
bool friend operator < (Node a, Node b){
if(a.x != b.x)
return a.x < b.x;
return a.y < b.y;
}
}cnt[1023];
bool hash_search(int x,int a, int b){
Point *pt = pnd[x];
// c//out<<"x = "<<x<<"a = "<<a<<" b = "<<b<<endl;
while(pt){
if(pt -> x == a && pt -> y == b){
return true;break;
}
pt = pt -> next;
}
return false;
}
int main(){
int n,n_p = 0;
while (scanf("%d", &n) != EOF && n){
n_p = 0;
memset(pnd, 0, sizeof(pnd));
for(int i = 0; i < n ; i++){
scanf("%d%d",&a, &b);
cnt[i].x = a;cnt[i].y = b;
int key = abs(a + b) % M;
if(!hash_search(key, a, b)){
p[n_p].x = a;
p[n_p].y = b;//cout<<"a = "<<a<<" b = "<<b<<endl;
p[n_p].next = pnd[key];
pnd[key] = &p[n_p];
n_p++;
}
}
/*for(int i = 0; i < n; i++){
Point *it = pnd[i];
while(it){
cout<<it -> x<<" "<<it -> y<<" ";
it = it -> next;
}
cout<<endl;
}*/
sort(cnt, cnt + n);
int ans = 0;
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
int dx = cnt[j].x - cnt[i].x;
int dy = cnt[j].y - cnt[i].y;
int x = cnt[i].x - dy;
int y = cnt[i].y + dx;
if(hash_search(abs(x + y) % M, x, y)){
int x = cnt[j].x - dy;
int y = cnt[j].y + dx;
if(hash_search(abs(x + y) % M, x, y))
ans ++;
}
}
}
printf("%d\n",ans / 2);
}
return 0;
}
AC2:
/*=============================================================================
#
# Author: liangshu - cbam
#
# QQ : 756029571
#
# School : 哈尔滨理工大学
#
# Last modified: 2015-08-26 18:31
#
# Filename: B.cpp
#
# Description:
# The people who are crazy enough to think they can change the world, are the ones who do !
=============================================================================*/
#
#include<iostream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cctype>
#include<string>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
const int M = 1031;
struct Point{
int x, y;
};
Point p[1023];
int n, hash[M + 8], next[1023];
bool cmp(const Point & a, const Point & b){
if(a.x != b.x)
return a.x < b.x;
return a.y < b.y;
}
int hashcode(const Point&tp){
return abs(tp.x + tp.y ) % M;
}
bool hash_search(const Point &tp){
int key = hashcode(tp);
int i = hash[key];
while(i != -1){
if(tp.x == p[i].x && tp.y == p[i].y){
return true ;
}
i = next[i];
}
return false ;
}
void insert_hash(int i){
int key = hashcode(p[i]);
next[i] = hash[key];
hash[key] = i;
}
int main(){
Point p3, p4;
int dx, dy, ans;
while(scanf("%d",&n) != EOF && n){
memset(hash, -1, sizeof(hash));
memset(next, -1, sizeof(next));
for(int i = 0; i < n; i++){
scanf("%d %d",&p[i].x, &p[i].y);
}
ans = 0;
sort(p, p + n, cmp);
for(int i = 0; i < n; i++)
insert_hash(i);
ans = 0;
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
int dx = p[j].x - p[i].x;
int dy = p[j].y - p[i].y;
p3.x = p[i].x + dy;
p3.y = p[i].y - dx;
if(hash_search(p3))
{
p4.x = p[j].x + dy;
p4.y = p[j].y - dx;
if(hash_search(p4))
ans ++;
}
}
}
printf("%d\n", ans/2);
}
return 0;
}