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 命令——5 rm(转)
昨天学习了创建文件和目录的命令mkdir ,今天学习一下linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所 ...
- 2018.10.24 NOIP2018模拟赛 解题报告
得分: \(100+0+100=200\)(\(T2\)悲惨爆\(0\)) \(P.S.\)由于原题是图片,所以我没有上传题目描述,只有数据. \(T1\):query(点此看题面) 熟悉主席树的人都 ...
- gearmand 编译 Unable to find libevent
如果出现configure: error: Unable to find libevent,则输入命令:yum -y install libevent libevent-devel然后重新config ...
- python_42_文件补充
m=['红烧肉\n','熘肝尖','西红柿炒鸡蛋','腊八粥','油焖大虾'] fname=input("请输入文件名:")#输入xxx f=open(fname,'w',enco ...
- winform下读取excel文件并绑定datagridview例子
首先我要读取这个excel文件然后生成Datable 用winform编程的方式 前台界面: 后台的代码 using System; using System.Collections.Generic; ...
- [未完] term.js 记录遇到的问题
参考博文:https://www.cnblogs.com/zhenfei-jiang/p/7065038.html 按照网上查找的资料敲了代码 term.on('data', function(dat ...
- 手写promise
写在前面: 在目前的前端分开中,我们对于异步方法的使用越来越频繁,那么如果处理异步方法的返回结果,如果优雅的进行异步处理对于一个合格的前端开发者而言就显得尤为重要,其中在面试中被问道最多的就是对Pro ...
- PAT 乙级 1017
题目 题目地址:PAT 乙级 1017 题解 粗看是一道大数除法题,实际上只不过是通过字符数组模拟除法过程,理解之后还是比较简单的: 具体分析一下本题: 因为题设中的除数(n)是一位整数,因此大幅简化 ...
- 二十、Mysql 连接的使用
Mysql 连接的使用 在前几章节中,我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据. 本章节我们将向大家介绍如何使用 MySQL 的 JOIN ...
- [Python]有关pygame库中的flip和update的区别
pygame.display.flip()和pygame.display.update()的用法上的区别: 资料一. 资料二. (资料最后更新时间:2019年1月9日)