Description

There are N points in total. Every point moves in certain direction and certain speed. We want to know at what time that the largest distance between any two points would be minimum. And also, we require you to calculate that minimum distance. We guarantee that no two points will move in exactly same speed and direction.      
              

Input

The rst line has a number T (T <= 10) , indicating the number of test cases.        For each test case, first line has a single number N (N <= 300), which is the number of points.        For next N lines, each come with four integers X i, Y i, VX i and VY i (-10 6 <= X i, Y i <= 10 6, -10 2 <= VX i , VY i <= 10 2), (X i, Y i) is the position of the i th point, and (VX i , VY i) is its speed with direction. That is to say, after 1 second, this point will move to (X i + VX i , Y i + VY i).      
              

Output

For test case X, output "Case #X: " first, then output two numbers, rounded to 0.01, as the answer of time and distance.      
              

Sample Input

2
2
0 0 1 0
2 0 -1 0
2
0 0 1 0
2 1 -1 0

Sample Output

Case #1: 1.00 0.00
Case #2: 1.00 1.00

题目大意就是给定n个点的坐标和它x和y方向的分速度,要求在任意时刻两两点之间距离最大值中的最小值。

根据距离公式可以推断出对于某两个点在t逐渐增大的过程中距离服从二次函数。

于是就是对于n个二次抛物线求任意时刻最高点合成的图像。

可以证明(反证)合成的图像也是由两个单调性相反的图像构成(类似于抛物线)。

于是可以采用模拟退火的退化(类似爬山算法)来查找最值。

从minT从0时刻出发,首先设定步长dt = 1e8。然后对于minT-dt和minT+dt讨论,如果使最大值变小,自然更新minT,然后按比例k衰减dt。

直到dt满足精度要求。

进过测试比例k=0.9是可以满足的,跑了530MS;k = 0.95略慢些,跑了1.3S。

网上也有好多使用的是三分法。

这里贴出退火的代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <string>
#define LL long long
#define eps 1e-5 using namespace std; typedef pair<double, double> pdd; int x[], y[], vx[], vy[], n;
double minT, minDis; double pow2(double k)
{
return k*k;
} double calDis(double t)
{
double dis2 = ;
for (int i = ; i < n; ++i)
{
for (int j = i+; j < n; ++j)
{
if (i == j)
continue;
dis2 = max(dis2,
pow2(x[i]+vx[i]*t-x[j]-vx[j]*t) + pow2(y[i]+vy[i]*t-y[j]-vy[j]*t));
}
}
return sqrt(dis2);
} void qt()
{
double dt = 1e8, t, dis, k = 0.9, v;
minT = ;
minDis = calDis(minT); while (dt > eps)
{
dis = calDis(minT+dt);
t = minT + dt;
if (minT-dt >= )
{
v = calDis(minT-dt);
if (v < dis)
{
dis = v;
t = minT - dt;
}
}
if (dis < minDis)
{
minDis = dis;
minT = t;
}
dt *= k;
}
} void Work()
{
scanf("%d", &n);
for (int i = ; i < n; ++i)
scanf("%d%d%d%d", &x[i], &y[i], &vx[i], &vy[i]);
qt();
} int main()
{
//freopen("test.in", "r", stdin);
int T;
scanf("%d", &T);
for (int times = ; times <= T; ++times)
{
printf("Case #%d: ", times);
Work();
printf("%.2lf %.2lf\n", minT, minDis);
}
return ;
}

ACM学习历程—HDU4717 The Moving Points(模拟退火 || 三分法)的更多相关文章

  1. ACM学习历程—POJ3090 Visible Lattice Points(容斥原理 || 莫比乌斯)

    Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal ...

  2. HDU-4717 The Moving Points(凸函数求极值)

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  3. ACM学习历程——HDU5017 Ellipsoid(模拟退火)(2014西安网赛K题)

    ---恢复内容开始--- Description Given a 3-dimension ellipsoid(椭球面) your task is to find the minimal distanc ...

  4. 完成了C++作业,本博客现在开始全面记录acm学习历程,真正的acm之路,现在开始

    以下以目前遇到题目开始记录,按发布时间排序 ACM之递推递归 ACM之数学题 拓扑排序 ACM之最短路径做题笔记与记录 STL学习笔记不(定期更新) 八皇后问题解题报告

  5. ACM学习历程—HDU 5512 Pagodas(数学)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5512 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是给了初始的集合{a, b},然后取集合里 ...

  6. ACM学习历程—HDU5521 Meeting(图论)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是一个人从1开始走,一个人从n开始走.让最 ...

  7. ACM学习历程—HDU2476 String painter(动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意是给定一个起始串和一个目标串,然后每次可以将某一段区间染成一种字符,问从起始串到目标串最少需要染多 ...

  8. ACM学习历程—HDU5700 区间交(树状数组 && 前缀和 && 排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=5700 这是这次百度之星初赛2B的第五题.省赛回来看了一下,有这样一个思路:对于所有的区间排序,按左值排序. 然后 ...

  9. ACM学习历程—HDU5701 中位数计数(中位数 && 计数排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=5701 这是这次百度之星初赛2B的第六题.之前白山云做过类似的题,省赛完回来,我看了一下大概就有这样的思路:首先枚 ...

随机推荐

  1. List集合的遍历方法

    估计你永远都不会忘记这三个方法了...... public static void main(String[] args) { //超级for循环遍历方法 List<String> lis ...

  2. PHP session回收机制(转)

    由于PHP的工作机制,它并没有一个daemon线程,来定时地扫描session信息并判断其是否失效.当一个有效请求发生时,PHP会根据全局变量 session.gc_probability/sessi ...

  3. 我的ngnix 配置内容

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  4. 07 redi sorder set结构及命令详解

    zadd key score1 value1 score2 value2 .. 添加元素 redis 127.0.0.1:6379> zadd stu 18 lily 19 hmm 20 lil ...

  5. python 基础 3.2 文件 for 练习

    #/usr/bin/python #coding=utf-8 #@Time   :2017/11/1 22:19 #@Auther :liuzhenchuan #@File   :1030-1031练 ...

  6. python 基础2.5 循环中continue与breake用法

    示例1: #循环退出,break continue.break 跳出最外层循环:continue跳出内层循环 #当 i=5时,通过continue 跳出当前if循环,不在执行if循环中后边的语句.i= ...

  7. git merge的本质

    1 git merge [branch] 将[branch]这个分支merge到当前分支. 2 merge的本质 merge就是把branch上的提交合入当前分支的提交树,这两个分支上的所有提交的历史 ...

  8. LigerUI java SSH小例子

    1.新建web project 2.ssh框架 加入到项目中去(这里不介绍,网上搜索) 3.struts2配置 http://www.cnblogs.com/istianyu/archive/2013 ...

  9. json字符串转集合或者数组

    import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util. ...

  10. Tomcat学习笔记【5】--- 项目部署详解

    本文主要讲在Tomcat中部署项目的几种方式:静态部署.动态部署. 一 静态部署 静态部署项目有好几种方式,比较典型的有如下4种: 1.1 方式一:将Web项目放到webApps目录下 直接将web项 ...