POJ 1971 Parallelogram Counting
题目链接:
http://poj.org/problem?id=1971
题意:
二维空间给n个任意三点不共线的坐标,问这些点能够组成多少个不同的平行四边形。
题解:
使用的平行四边形的判断条件:对角线互相平分的四边形是平行四边形。
所以我们枚举每一条线段,如果有两条线段的中点是重合的,那么这四个顶点就能构成一个平行四边形,也就是说每条线段我们只要维护中点就可以了。
1、map维护中点:(数据比较大,t了)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<utility>
using namespace std;
typedef long long LL; const int maxn = ; int n;
int x[maxn],y[maxn];
map<pair<int,int>,int> mp; void init(){
mp.clear();
} int main(){
int tc;
scanf("%d",&tc);
while(tc--){
init();
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d%d",x+i,y+i);
}
int ans=;
for(int i=;i<n;i++){
for(int j=i+;j<n;j++){
ans+=mp[make_pair(x[i]+x[j],y[i]+y[j])];
mp[make_pair(x[i]+x[j],y[i]+y[j])]++;
}
}
printf("%d\n",ans);
}
return ;
}
2、用hash做(vector来建表)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<utility>
#include<vector>
using namespace std;
typedef long long LL; const int maxn = ;
//可能是因为vector<int> tab[mod]的初始化影响很大
//1e3+7跑2985MS 1e4+7跑1282MS 1e5+7跑1750MS 1e6+7跑4532MS
const int mod = 1e3+; struct Point {
int x, y, cnt;
Point(int x, int y, int cnt = ) :x(x), y(y), cnt(cnt) {}
Point() { cnt = ; }
}pt[maxn]; int n;
vector<Point> tab[mod];
int Hash(const Point& p) {
//LL tmp = (p.x) *1000000007 + p.y;
int tmp = ((p.x << ) + (p.x >> )) ^ (p.y << ); //折叠法,比上面一个稍微快一点
//注意哈希出来的要是非负数
tmp = (tmp%mod + mod) % mod;
return tmp;
} int add(const Point& p) {
int key = Hash(p);
int pos = -;
for (int i = ; i<tab[key].size(); i++) {
Point& tmp = tab[key][i];
if (p.x == tmp.x&&p.y == tmp.y) {
pos = i; break;
}
}
int ret = ;
if (pos == -) {
tab[key].push_back(Point(p.x, p.y, ));
}
else {
ret = tab[key][pos].cnt;
tab[key][pos].cnt++;
}
return ret;
} void init() {
for (int i = ; i<mod; i++) tab[i].clear();
} int main() {
int tc;
scanf("%d", &tc);
while (tc--) {
init();
scanf("%d", &n);
for (int i = ; i<n; i++) {
scanf("%d%d", &pt[i].x, &pt[i].y);
}
int ans = ;
for (int i = ; i<n; i++) {
for (int j = i + ; j<n; j++) {
Point p = Point(pt[i].x + pt[j].x, pt[i].y + pt[j].y);
ans += add(p);
}
}
printf("%d\n", ans);
}
return ;
}
3、用邻接表做散列表,初始化可以省一些时间 954MS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<utility>
#include<vector>
using namespace std;
typedef long long LL; const int maxn = ; const int mod = 1e6+; struct Point {
int x, y, cnt, ne;
Point(int x, int y, int cnt = ) :x(x), y(y), cnt(cnt) {}
Point(int x, int y, int cnt, int ne) :x(x), y(y), cnt(cnt), ne(ne) { }
Point() { cnt = ; }
}pt[maxn],egs[maxn*maxn]; int n;
int tab[mod],tot;
int Hash(const Point& p) {
LL tmp = (p.x) * + p.y;
// int tmp = ((p.x << 2) + (p.x >> 4)) ^ (p.y << 10); //折叠法,比上面一个稍微快一点
//注意哈希出来的要是非负数
tmp = (tmp%mod + mod) % mod;
return tmp;
} int add(const Point& p) {
int key = Hash(p);
int pos = -,_p=tab[key];
while (_p != -) {
Point& e = egs[_p];
if (p.x == e.x&&p.y == e.y) {
pos = _p; break;
}
_p = e.ne;
}
int ret = ;
if (pos == -) {
egs[tot] = Point(p.x, p.y, , tab[key]);
tab[key] = tot++;
}
else {
ret = egs[pos].cnt;
egs[pos].cnt++;
}
return ret;
} void init() {
memset(tab, -, sizeof(tab));
tot = ;
} int main() {
int tc;
scanf("%d", &tc);
while (tc--) {
init();
scanf("%d", &n);
for (int i = ; i<n; i++) {
scanf("%d%d", &pt[i].x, &pt[i].y);
}
int ans = ;
for (int i = ; i<n; i++) {
for (int j = i + ; j<n; j++) {
Point p = Point(pt[i].x + pt[j].x, pt[i].y + pt[j].y);
ans += add(p);
}
}
printf("%d\n", ans);
}
return ;
}
POJ 1971 Parallelogram Counting的更多相关文章
- POJ 1971 Parallelogram Counting (Hash)
Parallelogram Counting Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6895 Acc ...
- POJ 1791 Parallelogram Counting(求平行四边形数量)
Description There are n distinct points in the plane, given by their integer coordinates. Find the n ...
- 计算几何 + 统计 --- Parallelogram Counting
Parallelogram Counting Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5749 Accepted: ...
- Parallelogram Counting(平行四边形个数,思维转化)
1058 - Parallelogram Counting PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit ...
- 1058 - Parallelogram Counting 计算几何
1058 - Parallelogram Counting There are n distinct points in the plane, given by their integer coord ...
- POJ 1971 统计平行四边形 HASH
题目链接:http://poj.org/problem?id=1971 题意:给定n个坐标.问有多少种方法可以组成平行四边形.题目保证不会有4个点共线的情况. 思路:可以发现平行四边形的一个特点,就是 ...
- POJ 2386 Lake Counting(深搜)
Lake Counting Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17917 Accepted: 906 ...
- poj - 2386 Lake Counting && hdoj -1241Oil Deposits (简单dfs)
http://poj.org/problem?id=2386 http://acm.hdu.edu.cn/showproblem.php?pid=1241 求有多少个连通子图.复杂度都是O(n*m). ...
- POJ 2386 Lake Counting
Lake Counting Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 28966 Accepted: 14505 D ...
随机推荐
- js 里常用的字符串操作方法
/*var str='啦啦啦'; var str1='哈哈哈' //charAt() 返回指定索引处的字符串 console.log(str.charAt(3)) //charCodeAt() 返回指 ...
- vue-nuxt.js部署到宝塔主机服务器
废话不多说,直接上步骤,如下: 本文章为在 vue环境下使用了nuxt.js 1.搭建环境--由于本人安装的是宝塔主机,因此如下: 由于我直接使用的是宝塔主机,直接去“软件管理”安装 PM2管理器. ...
- Composer管理thinkphp版本
安装Composer 下载 Composer 安装前请务必确保已经正确安装了 PHP.打开命令行窗口并执行 php -v 查看是否正确输出版本号. 打开命令行并依次执行下列命令安装最新版本的 Comp ...
- 20155229 2016-2017-2 《Java程序设计》第十周学习总结
20155229 2016-2017-2 <Java程序设计>第十周学习总结 教材学习内容总结 网络 网络分为局域网.广域网.城域网 一次HTTP请求包含3个部分:①方法--统一资源标识符 ...
- # 第二周c实践所遇见的问题
第二周c实践所遇见的问题 地址符 在编程练习中时常忘记写入地址符,造成过运行错误,运行结果错误的惨痛教训,一个小小的错误耗费了很长的时间来寻找错误之处,养成写代码的一些好习惯势在必行.牢记scanf( ...
- nth-child()伪类选择器
描述: 伪类:nth-child()的参数是an+b,如果按照w3.org上的描述,写成中文,很可能会让人头晕,再加上笔者的文笔水平有限,所以我决定避开an+b的说法,把它拆分成5种写法共5部分来说明 ...
- 最简单的rman操作
连接: [root@oracle000 ‾]# su - oracle [oracle@oracle000 ‾]$ rman target / lines) Recovery Manager: Rel ...
- idea 从javadoc中复制内容出来
打开 tool window就行了 经验:百度google不到的东西太多了,要学会自己想办法,至少也要把功能都试一遍吧, 而且像这种东西官方一般会给方法实现你的目的,只不过有时候是把功能迁移了或者整合 ...
- R的数据读写
目录 1 简介 在使用任何一款数据分析软件的时候,首先要做的就是数据成功的读写问题,所以不同于其他文档的书写方法,本文将探讨如何读写本地文本文件. 2 运行环境 操作系统:Win10 R版本:R-3. ...
- c# IE浏览器清除缓存没用
再想买更新JS和css文件之后, 使用 internet 里面的删除选项 发现样式和事件还是没用变 最终发现 需要 按 f12 找到这个清缓存才正常解决问题