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. 【OpenStack】OpenStack系列17之OpenStack私有云设计一

    [软件系统] 1.操作系统(Minimal最小化安装): CentOS-6.6-x86_64,CentOS 6最后一个版本,官方建议版本. 相对于6.5版本: 强化对 SCSI 设备的处理,有助应付某 ...

  2. Coin Change

    You are given coins of different denominations and a total amount of money amount. Write a function ...

  3. 更改SharePoint 2010 顶部导航为下拉菜单样式

      更改SharePoint 2010 顶部导航为下拉菜单样式 最后的效果图: 假如一个网站集顶级站点下面有子网站:sub site1,该子站点下面又有两个子站点:sub site1_1,sub si ...

  4. Django的Context和RequestContext

    参考:http://www.dannysite.com/blog/38/ Django的模板渲染中,Context可以用来传递数据,一个Context是一系列变量和值的集合,它和Python的字典有点 ...

  5. encode和decode

    Python字符串的encode与decode研究心得乱码问题解决方法 为什么会报错“UnicodeEncodeError: 'ascii' codec can't encode characters ...

  6. 那些臭名昭著的sql

    两个或多个表关联,没写where条件,大量的笛卡尔值,严重时会导致数据库有问题. select * from a, b left join c on b.id = c.id left join d o ...

  7. Cocos2d 中的Sprite大小调整问题

    以前用UIImageView,比如  UIImageView *view = [[UIImageViewalloc] initWithImage:[UIImageimageNamed:@"b ...

  8. 8.python笔记之面向对象基础

    title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...

  9. poj 2421 Constructing Roads 解题报告

    题目链接:http://poj.org/problem?id=2421 实际上又是考最小生成树的内容,也是用到kruskal算法.但稍稍有点不同的是,给出一些已连接的边,要在这些边存在的情况下,拓展出 ...

  10. 【读书笔记】读《JavaScript设计模式》之工厂模式

    一个类或对象中往往会包含别的对象.在创建这种成员对象时,你可能习惯于使用常规方式,也即用new关键字和类构造函数.问题在于这回导致相关的两个类之间产生依赖性. 工厂模式用于消除这两个类之间的依赖性,它 ...