【P2742】包围奶牛
时间:2019-09-17
本文章向大家介绍【P2742】包围奶牛,主要包括【P2742】包围奶牛使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
嘛开学了佛系更,另外CSP也不远了
如题,随便找篇blog就能好好学习的东西 。。
这篇,大意是:观察到一个包从最左边的点走下半部分到最右边围起来的点斜率大小单调上升。上半部分类似
实现仔细想想应该不难(吧),拿下半部分为例:首先从左到右从下到上给点们排序,拿个栈来存点们,目标是到最后让栈内的点全都是下/上部分包围圈所需的点。一开始往栈里放拍最前两个点,然后开始加点:
如果新加进去的点与栈尾点的斜率比栈尾点与倒数第二个点的斜率大(如图,红点是栈内点),即形成包围态势,则直接让新点入栈。
(让黑点进了栈
否则:如图,新加进去的点(4)与栈尾点(3)的斜率比栈尾点(3)与倒数第二个点(2)的斜率小
则不是包围态势。此时踢掉点三(它不是包上的点):
再次检查,发现新加进去的点(4)与栈尾点(2)的斜率比栈尾点(2)与倒数第二个点(1)的斜率小,还不是包围态势,所以重复一次上面的操作,踢掉点二:
此时没什么好检查的了,把4点入栈,直接开始加下一个点。
如此反复直到对所有点都进行了一次入栈的操作并在期间踢出不满足条件的点。最后栈内只剩下下半部分包的点。一个个拿出来算距离和。
上半部分类似啦。
然后注意一点,两点组成的包就是两点间距离*2,要围起来的嘛。别做那些奇奇怪怪的剪纸就没问题力
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<stack> #include<cmath> #define MAXN 1000001 #define spc 1010101010 //特判k不存在 using namespace std; int N; double ans; struct cows{double x,y;}cow[10001]; stack<cows>zhan; inline double caldis(cows a, cows b){return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));}//卡常成性 inline double slope(cows a, cows b){return b.x==a.x ? spc : (b.y-a.y)/(b.x-a.x);}//计算a发射到b的斜率(斜率是slope这个没问题吧 bool cmp(cows a, cows b){return a.x==b.x ? a.y<b.y : a.x<b.x ;} int main(){ cin>>N; for(int i=1; i<=N; i++) cin>>cow[i].x>>cow[i].y; if(N<=1){printf("0.00");return 0;} if(N==2){ans=2*caldis(cow[1],cow[2]);printf("%.2lf",ans);return 0;} sort(cow+1,cow+1+N,cmp); //现在开始搜包的下半边。 zhan.push(cow[1]); zhan.push(cow[2]); int j=3; double k=slope(cow[1],cow[2]); while(j<=N) { cows c=zhan.top(); while(slope(c,cow[j])<k) { zhan.pop(); c=zhan.top(); zhan.pop(); if(zhan.empty()){ zhan.push(c); k=slope(c,cow[j]); continue; } k=slope(zhan.top(),c); zhan.push(c); } zhan.push(cow[j]); k=slope(c,cow[j]); j++; } //现在开始把下半边周长算上 cows nowcow=zhan.top(); zhan.pop(); while(!zhan.empty()) { ans+=caldis(nowcow,zhan.top()); nowcow=zhan.top(); zhan.pop(); } //现在开始搜包的上半边。 zhan.push(cow[1]); zhan.push(cow[2]); j=3; k=slope(cow[1],cow[2]); while(j<=N) { cows c=zhan.top(); while(slope(c,cow[j])>k) { zhan.pop(); c=zhan.top(); zhan.pop(); if(zhan.empty()){ zhan.push(c); k=slope(c,cow[j]); continue; } k=slope(zhan.top(),c); zhan.push(c); } zhan.push(cow[j]); k=slope(c,cow[j]); j++; } //现在开始把上半边周长算上 nowcow=zhan.top(); zhan.pop(); while(!zhan.empty()) { ans+=caldis(nowcow,zhan.top()); nowcow=zhan.top(); zhan.pop(); } printf("%.2lf",ans); }
原文地址:https://www.cnblogs.com/snowysniper/p/11535639.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 数组属性和方法
- CMake入门实战——其他
- git报错,远程克隆和更新不下来解决方法
- CMake入门实战——生成安装包
- PyTorch 60分钟入门系列之PyTorch简介
- 解决Nginx转发http后不走https的问题 后端tomcat
- PyTorch 60分钟入门系列之自动求导
- Roslyn 打包 NuGet 包添加改动日志
- PyTorch 60分钟入门系列之神经网络
- Linux 是如何管理内存的?
- Jmeter 常用函数(17)- 详解 __substring
- Jmeter 常用函数(14)- 详解 __strLen
- Jmeter 常用函数(15)- 详解 __StringFromFile
- Jmeter 常用函数(16)- 详解 __split
- Jmeter 常用函数(18)- 详解 __isDefined
- Jmeter 常用函数(19)- 详解 __BeanShell