JZOJ 5267. 费马点问题
Description
给n个点,每个点的横纵坐标为[0,10000]内的整数,找出一个点,使这个点到其他所有点的距离之和最小,也就是求费马点。
找到的点可能是小数。
Input
第一行一个整数n表示点数,后面n行每行两个整数,表示点的坐标。
Output
第一行一个整数n表示点数,后面n行每行两个整数,表示点的坐标。
Sample Input
5
8 8
10 8
7 10
8 6
5 7
Sample Output
9.40
Data Constraint
对于30%数据n<=10
对于100%数据n≤100
Solution
经典的费马点问题,直接使用模拟退火算法——一个完完全全的贪心求近似最优解的算法。
引用一下度娘:
模拟退火算法(Simulate Anneal,SA)是一种通用概率演算法,用来在一个大的搜寻空间内找寻命题的最优解。模拟退火是由S.Kirkpatrick, C.D.Gelatt和M.P.Vecchi在1983年所发明的。V.Černý在1985年也独立发明此演算法。模拟退火算法是解决TSP问题的有效方法之一。模拟退火的出发点是基于物理中固体物质的退火过程与一般组合优化问题之间的相似性。模拟退火算法是一种通用的优化算法,其物理退火过程由加温过程、等温过程、冷却过程这三部分组成。
进入正题,我们在范围内随机 M=30M=30 个可能点,
并设置限制 lim=104lim=10^4 ,降温率 delta=0.99delta=0.99 ,温度下限阈值 Tmin=0.01T_{min}=0.01。
每次处理一个可能点 (xi,yi)(x_i,y_i) ,那么在矩形 (x±lim,y±lim)(x±lim,y±lim) 中随机出一个点 (x′i,y′i)(x_i',y_i') 。
O(N)O(N) 计算一次 (x′i,y′i)(x_i',y_i') 的答案,若能更新答案,就将 (xi,yi)(x_i,y_i) 移到 (x′i,y′i)(x_i',y_i') 。
最后把 lim=lim∗deltalim=lim*delta ,则继续处理每个可能点,直到 lim<=Tminlim 时停止。
Code
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
using namespace std;
const int N=10001,M=31,way[4][2]={{1,1},{-1,1},{-1,-1},{1,-1}};
struct data
{double x,y;
}a[N],b[M],t;
int n,mnx,mxx,mny,mxy;
double ans=1e9;
inline int read()
{int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w;
}
inline double get()
{double s=0;for(int i=1;i<=n;i++) s+=sqrt((t.x-a[i].x)*(t.x-a[i].x)+(t.y-a[i].y)*(t.y-a[i].y));return s;
}
inline int random(int x,int y)
{return x+rand()%(y-x+1);
}
int main()
{srand(time(NULL));n=read();mnx=mny=N;for(int i=1;i<=n;i++){a[i].x=read(),a[i].y=read();if(a[i].x<mnx) mnx=a[i].x;if(a[i].x>mxx) mxx=a[i].x;if(a[i].y<mny) mny=a[i].y;if(a[i].y>mxy) mxy=a[i].y;}for(int i=1;i<M;i++){b[i].x=random(mnx*N,mxx*N)*1.0/N;b[i].y=random(mny*N,mxy*N)*1.0/N;t=b[i];double p=get();if(p<ans) ans=p;}for(double lim=N;lim>0.01;lim*=0.99)for(int i=1;i<M;i++){t.x=random((b[i].x-lim)*N,(b[i].x+lim)*N)*1.0/N;t.y=random((b[i].y-lim)*N,(b[i].y+lim)*N)*1.0/N;double p=get();if(p<ans) ans=p,b[i]=t;}printf("%.2lf",ans);return 0;
}
JZOJ 5267. 费马点问题相关推荐
- 欧拉定理 费马小定理
前言 学基础数论的时候看过证明,然而很快就忘了,最近在学习高深一点的数论,于是再复习一下欧拉定理和费马小定理. 欧拉定理 内容 若正整数 \(a,n\) 互质,则 \(a^{\varphi(n)}\e ...
- 「欧拉定理」学习笔记(费马小定理)
欧拉定理:对于互质的两个正整数$a, n$,满足$a^{φ(n)} ≡ 1\ (mod\ n)$ 证明: 设集合$S$包含所有$n$以内与$n$互质的数,共有$φ(n)$个:$$S = \{ x_1 ...
- 【ACM】杭电OJ 4704 Sum (隔板原理+组合数求和公式+费马小定理+快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=4704 1.隔板原理 1~N有N个元素,每个元素代表一个1.分成K个数,即在(N-1)个空挡里放置(K-1)块隔板 ...
- 子段乘积(逆元费马小定理)+线段树做法
题解:一开始做这个题的时候想过尺取法,但是因为没有逆元的知识,不知道该如何不断删除左端元素.其实这题并不难想,设l,r为两端开始都置为1,当长度小于k的时候不断乘右端元素并取余,当长度等于k时删除左端 ...
- 【学习笔记】高斯整数、高斯素数、费马平方和(全部相关概念及例题详解)《初等数论及其应用》
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 以下内容摘自 我的文章:算法竞赛中的数论问题 - 数论全家桶(信奥 / 数竞 / ACM)作者孟繁宇, ...
- luogu P2613 【模板】有理数取余(费马小定理,乘法逆元)
整理的算法模板合集: ACM模板 目录 题目传送门 题目传送门 相当于是一个高精的费马小定理求乘法逆元.虽然数据达到了101000110^{10001}1010001,但是我们可以使用快读然后一直模m ...
- 关于素数常用结论--威尔逊定理、欧拉定理、费马小定理、米勒罗宾算法
再需要判定的数比较大时,用枚举法肯定不行的,但目前数学界也没有任何一种又快又准确的判定素数的方法,并且也证明了素数不存在任何一种通项表达式.但作为初等数论中最大的一部分内容,数学家们对素数性质进行了大 ...
- 迷倒高斯、费马、欧拉的女王,竟是低调的她
谁能想到,读一本书,能让人经历三次反转. 作为新媒体编辑,我总是能先人一步知道某本新书的动向:作者.内容.书名--而这本新出的<数学女王的邀请>,光名字就把我吓了一跳. 数学女王??谁?哪 ...
- 【BZOJ1951】【SDOI2010】古代猪文 Lucas定理、中国剩余定理、exgcd、费马小定理
Description "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久 ...
最新文章
- python aipspeech_Python调用百度API实现语音识别(二)
- oracle变态错误解决:ORA-00604: 递归 SQL 级别 2 出现错误
- 机房空调清理杨柳絮操作
- CodeForces - 1339E Perfect Triples(打表找规律)
- mysql基本常用命令
- centos安装最新版的docker-ce(二进制安装)
- c语言学习-编写函数求x的n次方的值
- Spring Boot 学习系列(04)—分而治之,多module打包
- 微软源代码遭 SolarWinds 黑客访问
- pythongui界面实例_wxPython:python首选的GUI库实例分享(5)
- [转]如何:定义和处理 SOAP 标头
- 大整数相乘python fft_Python带你理解用于信号同步的CAZAC序列
- 大数据要如何提高 才能满足智慧城市需求?
- 集成海康威视Sadp SDK实现获取设备参数配置
- 最全的搜索引擎入口和分类目录入口
- 计算机语言phal语言,phalapi
- 科学计算机怎么解一元一次方程,解一元一次方程“八不要”
- 如何增加公众号阅读量和粉丝
- 如何批量压缩pdf文件到最小
- Gitlab本地备份与远程机备份