[题解]UVA10902 Pick-up Sticks
题意简述
多测。给定坐标系上依次给定\(n\)根木棍的起始和终止坐标,按顺序放置这些木棍,询问最终处在最上层的木棍有哪些。
\(n\le 100000\)。保证任意时刻最上层的木棍不超过\(1000\)个。
思路分析
看起来数据范围很刁钻,不过除了暴力以外的方法想不出了,就写了一份上交,结果过了。
思路就是用链表记录最上层的木棍,每放一根木棍就遍历链表,如果有相交的就把这个木棍从链表中移出去。
遍历完链表,再把当前木棍加进去。
难点主要在于如何判断木棍相交。
在平面上判断两线段相交,需要同时使用“快速排斥实验”与“跨立实验”。
所谓快速排斥实验,就是先粗略地判断一下两线段支起的矩形是否相交。如果两个矩形都不相交,两线段肯定也不相交。

但仅仅矩形相交显然不能说线段相交。还需要进行跨立实验。
从线段\(1\)的一端向线段\(2\)的两端作\(2\)个向量。记录红色向量和橙色向量的方向关系为\(A\)(顺时针/逆时针/共线)。
再从线段\(1\)的另一端向\(2\)的两端作\(2\)个向量。记方向关系为\(B\)。
再用线段\(2\)向线段\(1\)重复上面的过程,记方向关系为\(C,D\)。
如果\(A\)和\(B\)都是顺时针或者都是逆时针,或者\(C,D\)都是顺时针或者都是逆时针,则说明\(1\)条线段的两个端点位于另一条线段所在直线的一端,自然两线段不相交。
否则说明\(1\)条线段的两个端点位于另一条线段所在直线的两端,又因为我们进行了快速排斥实验,保证了如果在另一条线段所在直线的两端,两线段一定相交。
注意到两向量可能出现共线的情况,这说明一定是某一点在一条线段上了。这种情况仍然是相交,所以不用参与判断。

跨立实验只能判断线段与直线的关系,配合快速排斥实验就可以判断线段与线段之间的关系了。
至于如何判断两向量的方向关系,就是用叉积了。两向量\(\vec{a}=(x_1,y_1),\vec{b}=(x_2,y_2)\)的叉积是一个向量,其长度为\(\vec{a}\times \vec{b}\)为\(x_1\times y_2-x_2\times y_1\)。该值:
\(>0\):\(\vec{a}\)在\(\vec{b}\)的顺时针方向。
\(<0\):\(\vec{a}\)在\(\vec{b}\)的逆时针方向。
\(=0\):\(\vec{a}\)和\(\vec{b}\)共线。
Code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
struct point{double x,y;};
struct segment{point a,b;};
double cross(point a,point b){return a.x*b.y-b.x*a.y;}
point vec(point a,point b){return {b.x-a.x,b.y-a.y};}
bool intersect(segment a,segment b){
if(max(b.a.x,b.b.x)<min(a.a.x,a.b.x)||min(b.a.x,b.b.x)>max(a.a.x,a.b.x)||
max(b.a.y,b.b.y)<min(a.a.y,a.b.y)||min(b.a.y,b.b.y)>max(a.a.y,a.b.y)) return 0;
double t1=cross(vec(b.a,a.a),vec(b.a,a.b))*cross(vec(b.b,a.a),vec(b.b,a.b));
double t2=cross(vec(a.a,b.a),vec(a.a,b.b))*cross(vec(a.b,b.a),vec(a.b,b.b));
if(t1>0||t2>0) return 0;
return 1;
}
int n;
list<pair<int,segment>> li;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
while(cin>>n){
if(!n) break;
li.clear();
for(int i=1;i<=n;i++){
segment ts;
cin>>ts.a.x>>ts.a.y>>ts.b.x>>ts.b.y;
for(auto it=li.begin();it!=li.end();){
if(intersect(ts,(*it).second)) it=li.erase(it);
else it++;
}
li.push_back({i,ts});
}
cout<<"Top sticks: ";
bool f=0;
for(auto i:li){
if(!f) f=1;
else cout<<", ";
cout<<i.first;
if(!f) f=1,cout<<", ";
}
cout<<".\n";
}
return 0;
}
[题解]UVA10902 Pick-up Sticks的更多相关文章
- 2015南阳CCPC D - Pick The Sticks dp
D - Pick The Sticks Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description The story happened lon ...
- 2015南阳CCPC D - Pick The Sticks 背包DP.
D - Pick The Sticks Description The story happened long long ago. One day, Cao Cao made a special or ...
- The 2015 China Collegiate Programming Contest D.Pick The Sticks hdu 5543
Pick The Sticks Time Limit: 15000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- CDOJ 1218 Pick The Sticks
Pick The Sticks Time Limit: 15000/10000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others ...
- HDU 5543 Pick The Sticks:01背包变种
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543 题意: 给你N个金条和一张长度为L的桌子.每个金条长度为a[i],价值为w[i].金条只能在桌子 ...
- UESTC 1218 Pick The Sticks
Time Limit: 15000/10000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Status ...
- hdu 5543 Pick The Sticks(动态规划)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543 题意:给你一根长为m的长木板和一些小木棒,每一根小木棒有它的长度和价值,这些小木棒要放在长木板上 ...
- DP(01背包) UESTC 1218 Pick The Sticks (15CCPC C)
题目传送门 题意:长度为L的金条,将n根金棍尽可能放上去,要求重心在L上,使得价值最大,最多有两条可以长度折半的放上去. 分析:首先长度可能为奇数,先*2.然后除了两条特殊的金棍就是01背包,所以dp ...
- [HDOJ5543]Pick The Sticks(DP,01背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543 题意:往长为L的线段上覆盖线段,要求:要么这些线段都在L的线段上,要么有不超过自身长度一半的部分 ...
- uestc oj 1218 Pick The Sticks (01背包变形)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1218 给出n根木棒的长度和价值,最多可以装在一个长 l 的容器中,相邻木棒之间不允许重叠,且两边上的木棒,可 ...
随机推荐
- 使用 frp 进行内网穿透
frp 是一个开源的内网穿透工具,可以使外网设备访问内网防火墙后的设备/服务器. 比如可以买一个 99元/年 的阿里云低配 ECS,然后把自己相对高配的旧电脑放在家里. 家里的旧电脑通过 frp 连上 ...
- sqlite:No module named _sqlite3
执行代码报错:"sqlite:No module named _sqlite3" 执行环境说明 某台服务器上执行DrissionPage相关程序报错,本机没有问题. 解决说明 本机 ...
- 【2020.11.14提高组模拟】无尽之前 (game) 题解
[2020.11.14提高组模拟]无尽之前 (game) 题解 有趣的题面 题目背景 雏见泽,一个和平的,或者说本应和平的小村庄,却因连续四年的怪死事件而蒙上了阴 影. 无一例外,每年的事件都发生在棉 ...
- 终极指南:Scrum中如何设置需求优先级
需求众多不知道如何下手?总想先做简单的需求,复杂需求却一拖再拖?那么,我们是时候开始考虑如何设置需求优先级了. 本期终极指南将展示如何为需求设置有效优先级,如何有效管理工作量,让效率指数倍增长,搭配 ...
- 「Note」树论方向
1. 重链剖分 1.1. 简介 重链剖分将树分割成若干链维护信息,将树的结构转换为线性结构,然后可用其他数据结构维护. 定义以下概念: 重子节点 轻子节点 重边 轻边 重链 某节点的子节点中子树大小最 ...
- 总决赛定档!“天翼云息壤杯”高校AI大赛巅峰之战即将打响!
近日,为梦想添翼,让AI发光--"天翼云息壤杯"高校AI大赛总决赛时间正式揭晓.总决赛将于2025年7月1日至7月17日在北京举办.届时,来自全国各地上百支成功晋级的优秀队伍和特邀 ...
- ChatMoney让你变成HR高手!
本文由 ChatMoney团队出品 在快节奏的现代职场中,招聘是每一个企业都绕不开的重要环节.然而,传统的招聘流程往往繁琐而低效,从海量简历的筛选,再到后续的评估与决策,每一个环节都耗费着HR人员大量 ...
- 鸿蒙Next仓颉语言开发实战教程:消息列表
大家好,今天要分享的是仓颉语言开发商城应用实战教程的消息列表页面. 这个页面的导航栏和之前有所不同,不过难度并没有增加,只是标题移到了左边,我们使用两端对齐方式就能实现,导航栏部分的具体代码如下: R ...
- Java源码分析系列笔记-3.volatile
目录 1. 是什么 2. 什么情况 volatile 比 synchronized 更合适 2.1. 例子 2.2. 无法停止的原因分析 2.3. 解决方法 2.4. volatile vs sync ...
- Blazor学习之旅 (13) Razor类库的使用
在上一篇我们学习了Blazor和JavaScript的互操作性,这一篇我们了解下如何创建和使用Razor类库. 什么是Razor类库? 我们都知道,在.NET应用程序中,我们可以通过NuGet来安装各 ...