-
时间:2016-04-15 18:40:17 星期五
-
题目编号:[2016-04-15][codeforces][660][D][Number of Parallelograms]
-
题目大意:给定n个点的坐标,问这些点能组成多少个平行四边形
-
分析:
- 每个平行四边形对角线互相平分,所以只要两条边的交点一样,那么这两条边(斜边)所对应的四边形就一定是平行四边形
- 所以,枚举所有交点,计算相同交点的个数 CntiCnti,那么ans=∑Cnti×(Cnti?1)2ans=∑Cnti×(Cnti?1)2
-
遇到的问题:
- 为了方便,计算交点的时候,没有除以2,但是在把点转换成一个数字来存的时候,x坐标乘了 1E9 ,应该乘2×1E9才对
- 第一次计数用了map来计算,但是时间花了2000+ms,
- 然后发现有100+ms,就是不用map存,直接把所有交点加入数组中,然后排序,计算相同点的个数
//234ms
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
const int maxn = 2000 + 10;
struct Point{
int x,y;
}p[maxn];
long long q[maxn*maxn];
int main(){
int n;
scanf("%d",&n);
for(int i = 0 ; i < n ; ++i){
scanf("%d%d",&p[i].x,&p[i].y);
}
int cnt = 0;
memset(q,-1,sizeof(q));
for(int i = 0 ; i < n ; ++i){
for(int j = i + 1 ; j < n ; ++j){
long long k =((long long) p[i].x + p[j].x)*1E9*2 + (p[i].y) + p[j].y;
q[cnt++] = k;
}
}
sort(q , q + cnt);
int k,ans = 0;
for(int i = 0 ; i < cnt - 1 ;++i){
k = 1;
while(i < cnt && q[i] == q[i + 1]){
++i;++k;
}
ans += k * (k - 1) / 2;
}
printf("%d\n",ans);
return 0;
}
//2214ms
#include<cstdio>
#include<map>
using namespace std;
struct Point{
int x,y;
Point(int a = 0,int b = 0):x(a),y(b){}
}p[2000 + 10];
map<long long,int > m;
int main(){
int n;
scanf("%d",&n);
for(int i = 0 ; i < n ; ++i){
scanf("%d%d",&p[i].x,&p[i].y);
}
for(int i = 0 ; i < n ; ++i){
for(int j = i + 1 ; j < n ; ++j){
long long k =((long long) p[i].x + p[j].x)*1E9*2 + (p[i].y) + p[j].y;
if(m.find(k) == m.end() ){
m[k] = 1;
}else ++m[k];
}
}
map<long long,int>::iterator itm;
int ans = 0;
for(itm = m.begin(); itm != m.end();++itm){
int n = itm -> second;
ans += n * (n - 1) / 2;
}
printf("%d\n",ans);
return 0;
}
时间: 2024-11-09 05:38:38