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+的代码题,偶尔还会写数学题.他找到 ...
随机推荐
- 使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数
最近Jerry接到一个原型开发的任务,需要在微信里调用ABAP On Premise系统(SAP CRM On-Premise)里的某些函数.具体场景和我之前的公众号文章 Cloud for Cust ...
- fiddle连接终端测试配置
第一次做app,对app的数据要进行一些数据抓包和数据分析,知道客户端发送到服务器端的过程和逻辑,通过抓包了解和分析出错,前提要先连接fiddle
- vuejs挂载点,模板与实例的关系
<body> <div id='root'> <h1>{{msg}}</h1> </div> <script> new Vue( ...
- python_28_dictionary补充
#update:合并两个字典,如果有交叉就覆盖更新,没有交叉的就创建 info={ 'stu1101':'Liu Guannan', 'stu1102':'Wang Ruipu', 'stu1103' ...
- java编程基础——二叉树的镜像
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 题目代码 /** * @program: JavaCode * @description: 操作给定的二叉树,将其变换为源二叉树的镜像. * 二 ...
- java,从键盘输入个数不确定的整数,并判断输入的正数和负数的个数,输入0时结束程序。
package study01; import java.util.Scanner; public class Test { public static void main(String[] args ...
- sql注入问题 java中将MySQL的数据库验证秘密加上 ' or '1'= '1 就可以出现万能密码
password的字符串中,加上 ' or '1'= '1 就可以制作出万能密码. 原因如下: 原代码中密码是123456 执行数据库查询语句 实际上执行的SQL语句是: select * from ...
- d3.js--01
D3 的全称是(Data-Driven Documents),顾名思义可以知道是一个被数据驱动的文档.听名字有点抽象,说简单一点,其实就是一个 JavaScript 的函数库,使用它主要是用来做数据可 ...
- 【搜索】【入门】洛谷P1036 选数
题目描述 已知 n个整数x1,x2,…,xn,以及1个整数k(k<n).从nn个整数中任选kk个整数相加,可分别得到一系列的和. 例如当n=4,k=3,4个整数分别为3,7,12,19时, ...
- 【组合数学】cf660E. Different Subsets For All Tuples
比较套路的组合数学题 For a sequence a of n integers between 1 and m, inclusive, denote f(a) as the number of d ...