http://poj.org/problem?id=2653

我很好奇为什么这样$O(n^2)$的暴力能过....

虽然说这是加了链表优化的,但是最坏不也是$O(n^2)$吗。。。(只能说数据太弱...)

然后本题裸的判线段相交和点在直线上...(看了网上的标程,不判端点的情况都能过我也是醉了...)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mkpii make_pair<int, int>
#define pdi pair<double, int>
#define mkpdi make_pair<double, int>
#define pli pair<ll, int>
#define mkpli make_pair<ll, int>
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
#define printarr1(a, b) for1(_, 1, b) cout << a[_] << '\t'; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; } const double eps=1e-6;
int dcmp(double x) { return abs(x)<eps?0:(x<0?-1:1); }
struct Point { double x, y; Point(double _x=0, double _y=0) : x(_x), y(_y) {} }; typedef Point Vector;
Vector operator- (Point &a, Point &b) { return Vector(a.x-b.x, a.y-b.y); }
bool operator== (Point &a, Point &b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; }
double Cross(Vector a, Vector b) { return a.x*b.y-b.x*a.y; }
double Dot(Vector a, Vector b) { return a.x*b.x+a.y*b.y; }
int SSjiao(Point p1, Point p2, Point q1, Point q2) {
return (dcmp(Cross(p1-q1, q2-q1))^dcmp(Cross(p2-q1, q2-q1)))==-2 &&
(dcmp(Cross(q1-p1, p2-p1))^dcmp(Cross(q2-p1, p2-p1)))==-2;
}
int onSegment(Point a, Point b, Point c) {
if(a==b || a==c) return -1;
if(dcmp(Cross(a-b, c-b))==0 && dcmp(Dot(b-a, c-a))==-1) return 1;
return 0;
} const int N=100015;
int nxt[N], ans[N];
Point a[N][2]; bool check(int now, int goal) {
if(onSegment(a[now][0], a[goal][0], a[goal][1]) ||
onSegment(a[now][1], a[goal][0], a[goal][1]) ||
onSegment(a[goal][0], a[now][0], a[now][1]) ||
onSegment(a[goal][1], a[now][0], a[now][1]) ) return 1;
if(SSjiao(a[now][0], a[now][1], a[goal][0], a[goal][1])) return 1;
return 0;
}
void del(int f, int now) { nxt[f]=nxt[now]; }
void work(int goal) {
int now=nxt[0], fa=0;
while(now!=goal) {
if(check(now, goal)) del(fa, now);
else fa=now;
now=nxt[now];
}
} int main() {
int n;
while(read(n), n) {
nxt[0]=1;
for1(i, 1, n) nxt[i]=i+1;
for1(i, 1, n) {
rep(k, 2) scanf("%lf%lf", &a[i][k].x, &a[i][k].y);
work(i);
}
printf("Top sticks: ");
int now=0, cnt=0;
while(nxt[now]!=n+1) {
ans[++cnt]=nxt[now];
now=nxt[now];
}
for1(i, 1, cnt-1) printf("%d, ", ans[i]); printf("%d.\n", ans[cnt]);
}
return 0;
}

  


Description

Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to find the top sticks, that is these sticks such that there is no stick on top of them. Stan has noticed that the last thrown stick is always on top but he wants to know all the sticks that are on top. Stan sticks are very, very thin such that their thickness can be neglected.

Input

Input consists of a number of cases. The data for each case start with 1 <= n <= 100000, the number of sticks for this case. The following n lines contain four numbers each, these numbers are the planar coordinates of the endpoints of one stick. The sticks are listed in the order in which Stan has thrown them. You may assume that there are no more than 1000 top sticks. The input is ended by the case with n=0. This case should not be processed.

Output

For each input case, print one line of output listing the top sticks in the format given in the sample. The top sticks should be listed in order in which they were thrown.

The picture to the right below illustrates the first case from input.

Sample Input

5
1 1 4 2
2 3 3 1
1 -2.0 8 4
1 4 8 2
3 3 6 -2.0
3
0 0 1 1
1 0 2 1
2 0 3 1
0

Sample Output

Top sticks: 2, 4, 5.
Top sticks: 1, 2, 3.

Hint

Huge input,scanf is recommended.

Source

【POJ】2653 Pick-up sticks(计算几何基础+暴力)的更多相关文章

  1. 【POJ】2318 TOYS(计算几何基础+暴力)

    http://poj.org/problem?id=2318 第一次完全是$O(n^2)$的暴力为什么被卡了-QAQ(一定是常数太大了...) 后来排序了下点然后单调搞了搞..(然而还是可以随便造出让 ...

  2. 【POJ 2653】Pick-up sticks 判断线段相交

    一定要注意位运算的优先级!!!我被这个卡了好久 判断线段相交模板题. 叉积,点积,规范相交,非规范相交的简单模板 用了“链表”优化之后还是$O(n^2)$的暴力,可是为什么能过$10^5$的数据? # ...

  3. BZOJ_1610_[Usaco2008_Feb]_Line连线游戏_(计算几何基础+暴力)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1610 给出n个点,问两两确定的直线中,斜率不同的共有多少条. 分析 暴力枚举直线,算出来斜率放 ...

  4. 二维计算几何基础题目泛做(SYX第一轮)

    题目1: POJ 2318 TOYS 题目大意: 给一个有n个挡板的盒子,从左到右空格编号为0...n.有好多玩具,问每个玩具在哪个空格里面. 算法讨论: 直接叉积判断就可以.注意在盒子的边界上面也算 ...

  5. 线段相交 POJ 2653

    // 线段相交 POJ 2653 // 思路:数据比较水,据说n^2也可以过 // 我是每次枚举线段,和最上面的线段比较 // O(n*m) // #include <bits/stdc++.h ...

  6. 2015南阳CCPC D - Pick The Sticks dp

    D - Pick The Sticks Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description The story happened lon ...

  7. poj 2653 线段与线段相交

    Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11884   Accepted: 4499 D ...

  8. CDOJ 1218 Pick The Sticks

    Pick The Sticks Time Limit: 15000/10000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others ...

  9. 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 ...

随机推荐

  1. 配置oss bucket cors

    到bucket中属性中选择跨越设置,点击添加规则会看到以下界面: 对应的输入如上即可.

  2. BZOJ 1058

    服气!我果然就是个傻逼. 傻兮兮地感觉两个数之间的差距无需删除一些答案,妈个鸡就只加入了一些新的答案忘记了去掉无效的答案.我果然是傻逼,经验不足脑子笨... 这么水的题...不说了,说多了都是泪. 自 ...

  3. Java--时间处理

    package javatest; import java.text.SimpleDateFormat; import java.util.Date; class timeTest{ public s ...

  4. 细微之处:比较两种CSS清除浮动的兼容

    http://www.cnblogs.com/bienfantaisie/archive/2011/05/27/2059597.html 清除浮动是连续浮动元素之后的必备工作,在工作中我做到需要清除浮 ...

  5. Java异常的栈轨迹fillInStackTrace和printStackTrace的用法

    本文转自wawlian 捕获到异常时,往往需要进行一些处理.比较简单直接的方式就是打印异常栈轨迹Stack Trace.说起栈轨迹,可能很多人和我一样,第一反应就是printStackTrace()方 ...

  6. sharepoint获取域名和当前登录的应为名字

    string a =  SPContext.Current.Web.CurrentUser.ToString(); int length = a.IndexOf("w|", 0) ...

  7. cenos配置

    #修复ifconfig1.查看 /sbin/ifconfig是否存在 echo $PATH2.查看ifconfig命令是否存在ls /sbin |grep ifconfig如果ifconfig命令存在 ...

  8. 解决ubuntu14.04下Qt 5.3.1下的QtCreator fcitx,ibus不能输入中文

    http://my.oschina.net/u/219482/blog/341452 感谢作者 ubuntu 14.04从Qt官网下载的最新版qt,安装过程很顺利,但却发现没办法输入中文(我用的是 f ...

  9. [转]使用VC/MFC创建一个线程池

    许多应用程序创建的线程花费了大量时间在睡眠状态来等待事件的发生.还有一些线程进入睡眠状态后定期被唤醒以轮询工作方式来改变或者更新状态信息.线程池可以让你更有效地使用线程,它为你的应用程序提供一个由系统 ...

  10. git branch -D 大写的D 删除分支

    今天删除本地分支 git branch -d XXX 提示:  the branch  XXX is not fully merged 原因:XXX分支有没有合并到当前分支的内容 解决方法:使用大写的 ...