fzu 2231 平行四边形数
2016-05-02 22:55
351 查看
题意:给出n个点,问哪四个点可以组成平行四边形
思路;要判别一个四边形是否是平行四边形,一个等价的判断条件是 两条边平行且相等,这样就是平行四边形,并且平行具有传递性,如果a//b,b//c,那么a//c,那么设g[i]为第i条边已经能组成平行四边形的个数,那么如果j//i且d[j]==d[i],g[j]=g[i]+1,可以在o(n)下处理,但要提前排好序,有点像dp的重复子问题,细节看代码
链接:http://acm.fzu.edu.cn/problem.php?pid=2231
思路;要判别一个四边形是否是平行四边形,一个等价的判断条件是 两条边平行且相等,这样就是平行四边形,并且平行具有传递性,如果a//b,b//c,那么a//c,那么设g[i]为第i条边已经能组成平行四边形的个数,那么如果j//i且d[j]==d[i],g[j]=g[i]+1,可以在o(n)下处理,但要提前排好序,有点像dp的重复子问题,细节看代码
链接:http://acm.fzu.edu.cn/problem.php?pid=2231
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> using namespace std; const int inf = 0x3f3f3f3f; const double eps = 1e-8; int x[505], y[505]; typedef long long ll; struct node { int x, y; }a[505];//存所有的点 struct edge { int x1,y1,x2, y2,k2,k1; ll d; double k,b; } b[300000];//存的是所有的边 ,最多有500*499条边 int g[300000]; ll cal(int x1, int y1, int x2, int y2)//边长 { return (ll)abs(x1-x2)*abs(x1-x2) + (ll)abs(y1-y2)*abs(y1-y2); } int gcd(int a,int b) { return b==0?a:gcd(b, a%b); } void calk(int x1, int y1, int x2, int y2,int &x, int &y)//计算该边斜率 { x = x1-x2; y = y1 - y2; int d = gcd(x, y); x/=d, y/=d; } bool cmp(const edge &a, const edge &b)//先按距离排序,再按斜率排序 { if(a.d!=b.d) return a.d<b.d; else { return a.k<b.k; } } int main() { int n; while(~scanf("%d", &n)) { for(int i=0; i<n; i++) { scanf("%d%d", &a[i].x, &a[i].y); } int cnt = 0; for(int i=0; i<n; i++) { for(int j=i+1; j<n; j++) { b[cnt].x1 = a[i].x,b[cnt].y1 = a[i].y; b[cnt].x2 = a[j].x,b[cnt].y2 = a[j].y; b[cnt].d =cal(a[i].x, a[i].y,a[j].x,a[j].y; if(b[cnt].x1==b[cnt].x2) b[cnt].k = inf; else { calk(a[i].x, a[i].y,a[j].x,a[j].y, b[cnt].k2,b[cnt].k1); b[cnt].k = (double)b[cnt].k1/b[cnt].k2; b[cnt].b = (double)b[cnt].y1 - b[cnt].k*b[cnt].x1; } cnt++;//y = kx+b; } } int ans =0; memset(g, 0, sizeof(g)); sort(b, b+cnt, cmp); for(int i= 1; i<cnt; i++) { if(b[i].d==b[i-1].d&&(fabs(b[i].k-b[i-1].k)<eps))//两条边边长相等,斜率相等 { if(b[i].x1==b[i].x2)//平行y轴,则斜率为无限大 { if(b[i].x1!=b[i-1].x1) { g[i]=g[i-1]+1; ans += g[i]; } } else if(fabs(b[i].k-0)<eps) //平行x轴, 则斜率为0 { if(b[i].y1!=b[i-1].y1) { g[i]=g[i-1]+1; ans += g[i]; } } else { if(fabs(b[i].b-b[i-1].b)>eps)//两直线必须保证b不相等, { g[i]=g[i-1]+1; ans += g[i]; } } } } printf("%d\n", ans/2);//因为一个平行四边有两组边平行且相等,所以重复算了两次 } return 0; }
相关文章推荐
- FZU 2231 平行四边形数
- 强大的U盘启动盘制作工具Rufus
- JAVA语言之基数排序
- OpenAuth.net
- MATLAB与C/C++混合编程之MATLAB调用C程序
- String abc=null;String abc="";String abc;三种写法有什么区别?
- [算法导论] 快速排序
- JDBC笔记-Transaction
- 轴承故障诊断
- 友元
- shell中各种括号的作用()、(())、[]、[[]]、{}
- 【转】获取Android控件的宽和高
- 关于Android中如何过滤HTML标签
- HDU 1297 Children’s Queue
- 10个惊艳的Swift单行代码
- 【GOF23设计模式】_工厂模式JAVA229-231
- 多种多样APP主界面Tab实现
- 启动、关闭外部进程ShellExecute() 、CreateProcess()、TerminateProcess()、OpenProcess()==
- ActiveMQ小记(二):基于ZooKeeper的HA方案
- 第95课:通过Spark Streaming的window操作实战模拟新浪微博、百度、京东等热点搜索词案例实战