HDU 2440、HDU 3694多边形费马点
1、http://acm.hdu.edu.cn/showproblem.php?pid=2440 按照题意知道是一个简单的多边形即凸包,但给出的点并没有按照顺序的,所以需要自己先求出凸包,然后在用随机淬火求费马点。
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<string>
- #include<cmath>
- #include<cstdlib>
- #include<queue>
- #include<stack>
- #include<map>
- #include<vector>
- #include<algorithm>
- #include<ctime>
- using namespace std;
- #define eps 1e-10
- int Fabs(double d)
- {
- if(fabs(d)<eps) return ;
- else return d>?:-;
- }
- struct point
- {
- double x,y;
- }p[],sta[];
- int oper[][]={,,,-,-,,,,,,,-,-,,-,-},top;
- double x_multi(point p1,point p2,point p3)
- {
- return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
- }
- double Dis(point p1,point p2)
- {
- return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
- }
- bool cmp(point a,point b)
- {
- if(Fabs(x_multi(p[],a,b))>) return ;
- if(Fabs(x_multi(p[],a,b))<) return ;
- if(Fabs(Dis(p[],a)-Dis(p[],b))<)
- return ;
- return ;
- }
- void Graham(int n)
- {
- int i,k=,tot;
- for(i=;i<n;i++)
- if((p[i].y<p[k].y)||((p[i].y==p[k].y)&&(p[i].x<p[k].x)))
- k=i;
- swap(p[],p[k]);
- sort(p+,p+n,cmp);
- tot=;
- for(i=;i<n;i++)
- if(Fabs(x_multi(p[i],p[i-],p[])))
- p[tot++]=p[i-];
- p[tot++]=p[n-];
- sta[]=p[],sta[]=p[];
- i=top=;
- for(i=;i<tot;i++)
- {
- while(top>=&&Fabs(x_multi(p[i],sta[top],sta[top-]))>=)
- {
- if(top==) break;
- top--;
- }
- sta[++top]=p[i];
- }
- }
- double allDis(int n,point f)
- {
- double sum=0.0;
- int i;
- for(i=;i<n;i++)
- sum+=Dis(sta[i],f);
- return sum;
- }
- point fermat(int n) //求费马点
- {
- double step=;
- int i,j;
- for(i=;i<n;i++)
- step+=fabs(sta[i].x)+fabs(sta[i].y);
- point f;
- f.x=,f.y=;
- for(i=;i<n;i++)
- f.x+=sta[i].x,f.y+=sta[i].y;
- f.x/=n,f.y/=n;
- point t;
- while(step>eps)
- {
- for(i=;i<;i++)
- {
- t.x=f.x+oper[i][]*step;
- t.y=f.y+oper[i][]*step;
- if(allDis(n,t)<allDis(n,f))
- f=t;
- }
- step/=;
- }
- return f;
- }
- int main()
- {
- int t,n,i;
- scanf("%d",&t);
- while(t--)
- {
- scanf("%d",&n);
- for(i=;i<n;i++)
- scanf("%lf%lf",&p[i].x,&p[i].y);
- Graham(n);
- point ans=fermat(top+);
- printf("%.0lf\n",allDis(top+,ans));
- if(t>) puts("");
- }
- return ;
- }
2、http://acm.hdu.edu.cn/showproblem.php?pid=3694 //求一个四边形的费马点,wrong了n次网上到处查才知道此题非常严谨,卡随机淬火算法。并且给出的四边形并不一定是凸四边形,所以需要讨论,如果是凸四边形,按照四边形的特性费马点就是对角线的交点,如果是凹的就是其中某一个顶点。
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<string>
- #include<cmath>
- #include<cstdlib>
- #include<queue>
- #include<stack>
- #include<map>
- #include<vector>
- #include<algorithm>
- #include<ctime>
- using namespace std;
- #define eps 1e-8
- int Fabs(double d)
- {
- if(fabs(d)<eps) return ;
- else return d>?:-;
- }
- struct point
- {
- double x,y;
- }p[],sta[];
- int oper[][]={,,,-,-,,,,,,,-,-,,-,-},top;
- double x_multi(point p1,point p2,point p3)
- {
- return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
- }
- double Dis(point p1,point p2)
- {
- return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
- }
- bool cmp(point a,point b)
- {
- if(Fabs(x_multi(p[],a,b))>) return ;
- if(Fabs(x_multi(p[],a,b))<) return ;
- if(Fabs(Dis(p[],a)-Dis(p[],b))<)
- return ;
- return ;
- }
- void Graham(int n)
- {
- int i,k=,tot;
- for(i=;i<n;i++)
- if((p[i].y<p[k].y)||((p[i].y==p[k].y)&&(p[i].x<p[k].x)))
- k=i;
- swap(p[],p[k]);
- sort(p+,p+n,cmp);
- /*tot=1;//下面直接用顶点个数判断是否为凸包,所以这里不去共线点
- for(i=2;i<n;i++)
- if(Fabs(x_multi(p[i],p[i-1],p[0])))
- p[tot++]=p[i-1];
- p[tot++]=p[n-1];*/
- sta[]=p[],sta[]=p[];
- i=top=;
- for(i=;i<n;i++)
- {
- while(top>=&&Fabs(x_multi(p[i],sta[top],sta[top-]))>=)
- {
- if(top==) break;
- top--;
- }
- sta[++top]=p[i];
- }
- }
- /*double allDis(int n,point f)
- {
- double sum=0.0;
- int i;
- for(i=0;i<n;i++)
- sum+=Dis(p[i],f);
- return sum;
- }
- point fermat(int n)
- {
- double step=0;
- int i,j;
- for(i=0;i<n;i++)
- step+=fabs(sta[i].x)+fabs(sta[i].y);
- point f;
- f.x=0,f.y=0;
- for(i=0;i<n;i++)
- f.x+=sta[i].x,f.y+=sta[i].y;
- f.x/=n,f.y/=n;
- point t;
- while(step>1e-10)
- {
- for(i=0;i<8;i++)
- {
- t.x=f.x+oper[i][0]*step;
- t.y=f.y+oper[i][1]*step;
- if(allDis(n,t)<allDis(n,f))
- f=t;
- }
- step/=2;
- }
- return f;
- }
- */
- int main()
- {
- int i,j;
- while(~scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p[].x,&p[].y,&p[].x,&p[].y,&p[].x,&p[].y,&p[].x,&p[].y))
- {
- if(p[].x==-&&p[].y==-&&p[].x==-&&p[].y==-&&p[].x==-&&p[].y==-&&p[].x==-&&p[].y==-)
- break;
- Graham();
- double ans;
- if(top==)
- ans=Dis(sta[],sta[])+Dis(sta[],sta[]);//凸四边形就直接取对角线交点
- else
- {
- ans=1e50;
- double sum=;
- for(i=;i<;i++)
- {
- sum=0.0;
- for(j=;j<;j++)
- if(i!=j)
- sum+=Dis(p[i],p[j]);
- ans=min(sum,ans);
- }
- }
- printf("%.4lf\n",ans);
- }
- return ;
- }
HDU 2440、HDU 3694多边形费马点的更多相关文章
- hdu 4704 Sum(组合,费马小定理,快速幂)
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4704: 这个题很刁是不是,一点都不6,为什么数据范围要开这么大,把我吓哭了,我kao......说笑的, ...
- HDU 1098 Ignatius's puzzle 费马小定理+扩展欧几里德算法
题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为 ...
- HDU 4704 Sum (隔板原理 + 费马小定理)
Sum Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/131072K (Java/Other) Total Submiss ...
- hdu 4704 Sum【组合数学/费马小定理/大数取模】By cellur925
首先,我们珂以抽象出S函数的模型:把n拆成k个正整数,有多少种方案? 答案是C(n-1,k-1). 然后发现我们要求的是一段连续的函数值,仔细思考,并根据组合数的性质,我们珂以发现实际上答案就是在让求 ...
- hdu 3694 10 福州 现场 E - Fermat Point in Quadrangle 费马点 计算几何 难度:1
In geometry the Fermat point of a triangle, also called Torricelli point, is a point such that the t ...
- 数论 --- 费马小定理 + 快速幂 HDU 4704 Sum
Sum Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=4704 Mean: 给定一个大整数N,求1到N中每个数的因式分解个数的 ...
- HDU 4704 Sum(隔板原理+组合数求和公式+费马小定理+快速幂)
题目传送:http://acm.hdu.edu.cn/showproblem.php?pid=4704 Problem Description Sample Input 2 Sample Outp ...
- hdu 4704(费马小定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4704 思路:一道整数划分题目,不难推出公式:2^(n-1),根据费马小定理:(2,MOD)互质,则2^ ...
- HDU 5667 Sequence【矩阵快速幂+费马小定理】
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5667 题意: Lcomyn 是个很厉害的选手,除了喜欢写17kb+的代码题,偶尔还会写数学题.他找到 ...
随机推荐
- linux 命令——17 whereis(转)
whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返回所有信息. 和 find相比,whereis查找的速度 ...
- linux 命令——11 nl (转)
nl命令在linux系统中用来计算文件中行号.nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等 ...
- ZOJ 2112 Dynamic Rankings(二分,树套树)
动态区间询问kth,单点修改. 区间用线段树分解,线段树上每条线段存一颗平衡树. 不能直接得到kth,但是利用val和比val小的个数之间的单调性,二分值.log^3N. 修改则是一次logN*log ...
- noip模拟赛#24
这套题我只会写第二题...我... T1:给出一个含有向边和无向边的混合图,如何确定无向边的方向使得图中不存在环.保证有解.多解情况输出任意解. =>我往最大流的残量网络的方向去想了...因为混 ...
- hdu-1068&&POJ1466 Girls and Boys---最大独立集
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1068 题目大意: 有n个人,一些人认识另外一些人,选取一个集合,使得集合里的每个人都互相不认识,求该 ...
- 问题 M: 克隆玩具
题目描述 你只有一个A类型玩具,现在有个有两种功能的机器:1. 加工一个A类型的玩具能够再得到一个A类型的玩具和一个B类型的玩具.2. 加工一个B类型的玩具,能得到两个B类型的玩具. 问经过多次加工之 ...
- 如何让图片相对于上层DIV始终保持水平、垂直都居中
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- python Scraping
http://docs.python-guide.org/en/latest/scenarios/scrape/
- 在mac下使用python抓取数据
2015已经过去,这是2016的第一篇博文! 祝大家新年快乐! 但是我还有好多期末考试! 还没开始复习,唉,一把辛酸泪! 最近看了一遍彦祖的文章叫做 iOS程序员如何使用Python写网路爬虫 所以自 ...
- 稍微深入点理解C++复制控制【转】
通过一个实例稍微深入理解C++复制控制过程,参考资料<C++ primer>,介绍点基本知识: 1.在C++中类通过特殊的成员函数:复制构造函数.赋值操作符和析构函数来控制复制.赋值和撤销 ...