HDU 3400(Line belt 三分套娃)
时间:2020-05-21
本文章向大家介绍HDU 3400(Line belt 三分套娃),主要包括HDU 3400(Line belt 三分套娃)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Line belt
思路
我们假定在\(A, B\)上选取点\(E\),在\(C, D\)上选取点\(F\),我们的移动路径是\(A -> E -> F -> D\)。
当我们确定\(E\)点时,不难发现\(dis(E -> F + F -> D)\)是一个凹函数,具有极小值。
当我们确定\(F\)点时不难发现\(dis(A -> E + E -> F)\)也是一个凹函数,具有极小值。
这两段函数连接起来,不难发现也是一个凹函数,具有极小值。
这就好像是一个套娃的三分了,我们可以通过确定\(E\)点,然后去找到\(min\ dis(E -> F + F -> D)\)
然后由于函数具有整体的凹性,我们只要通过基础的三分来三分点\(E\),就能确定最后的答案。
具体有一些细节在代码中。
代码
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
double P, Q, R;
struct point {
double x, y;
point(double a = 0.0, double b = 0.0) : x(a), y(b) {};
}A, B, C, D, E, F;
double dis(point a, point b) {
//这里我也是看了评论,不加eps就wa,
//好像如果不加eps会导致答案偏小。
return sqrt(eps + (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double calc2(double x) {
//通过长度和向量确定F点坐标,
//一定要注意坐标C, D的前后顺序,
F = point(C.x + (x / dis(C, D)) * (D.x - C.x), C.y + (x / dis(C, D)) * (D.y - C.y));
//cost(E -> F + F -> D)
return (dis(E, F) / R) + ((dis(C, D) - x) / Q);
}
double calc1(double x) {
//通过长度和向量来确定E点的坐标。
//一定要注意坐标A, B的前后顺序,
E = point(A.x + (x / dis(A, B)) * (B.x - A.x), A.y + (x / dis(A, B)) * (B.y - A.y));
double l = 0, r = dis(C, D);//从长度三分F点。
for(int i = 0; i < 100; i++) {
double lmid = l + (r - l) / 3;
double rmid = r - (r - l) / 3;
if(calc2(lmid) >= calc2(rmid)) l = lmid;
else r = rmid;
}
//calc2 + cost(A -> E)。
return calc2(l) + (x / P);
}
int main() {
// freopen("in.txt", "r", stdin);
int t; scanf("%d", &t);
while(t--) {
scanf("%lf %lf", &A.x, &A.y);
scanf("%lf %lf", &B.x, &B.y);
scanf("%lf %lf", &C.x, &C.y);
scanf("%lf %lf", &D.x, &D.y);
scanf("%lf %lf %lf", &P, &Q, &R);
double l = 0, r = dis(A, B);//从长度三分E点。
// cout << l << " " << r << endl;
for(int i = 0; i < 100; i++) {
double lmid = l + (r - l) / 3;
double rmid = r - (r - l) / 3;
if(calc1(lmid) >= calc1(rmid)) l = lmid;
else r = rmid;
}
// cout << l << " " << r << endl;
printf("%.2f\n", calc1(l));
// puts("");
}
return 0;
}
一组样例及答案
8
0 0 4 1
4 1 0 2
8 8 1
0 0 0 100
100 0 100 100
2 2 1
8 0 23 8
4 2 91 0
4 9 10
0 0 2 2
0 2 2 0
4 3 1
1 8 1000 10
0 689 10 1000
90 1 20
4 9 4 20
4 41 4 60
4 4 1
4 9 4 20
4 91 4 60
4 3 1
0 5 8 5
2 5 4 0
6 9 3
1.03
136.60
8.30
0.83
49.60
28.50
42.75
0.93
原文地址:https://www.cnblogs.com/lifehappy/p/12929612.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel model模型定义实现开启自动管理时间created_at,updated_at
- laravel ORM关联关系中的 with和whereHas用法
- thinkPHP事务操作简单案例分析
- php 多个变量指向同一个引用($b = &$a)用法分析
- 浅谈laravel5.5 belongsToMany自身的正确用法
- 在 PHP 和 Laravel 中使用 Traits的方法
- Laravel 修改默认日志文件名称和位置的例子
- php 命名空间(namespace)原理与用法实例小结
- Laravel Eloquent ORM 实现查询表中指定的字段
- Yii框架 session 数据库存储操作方法示例
- 使用laravel指定日志文件记录任意日志
- php实现微信小程序授权登录功能(实现流程)
- PHP封装请求类实例分析【基于Yii框架】
- php 多继承的几种常见实现方法示例
- PHP中通过getopt解析GNU C风格命令行选项