【POJ】2653 Pick-up sticks(计算几何基础+暴力)
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 Sample Output Top sticks: 2, 4, 5. Hint Huge input,scanf is recommended.
Source |
【POJ】2653 Pick-up sticks(计算几何基础+暴力)的更多相关文章
- 【POJ】2318 TOYS(计算几何基础+暴力)
http://poj.org/problem?id=2318 第一次完全是$O(n^2)$的暴力为什么被卡了-QAQ(一定是常数太大了...) 后来排序了下点然后单调搞了搞..(然而还是可以随便造出让 ...
- 【POJ 2653】Pick-up sticks 判断线段相交
一定要注意位运算的优先级!!!我被这个卡了好久 判断线段相交模板题. 叉积,点积,规范相交,非规范相交的简单模板 用了“链表”优化之后还是$O(n^2)$的暴力,可是为什么能过$10^5$的数据? # ...
- BZOJ_1610_[Usaco2008_Feb]_Line连线游戏_(计算几何基础+暴力)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1610 给出n个点,问两两确定的直线中,斜率不同的共有多少条. 分析 暴力枚举直线,算出来斜率放 ...
- 二维计算几何基础题目泛做(SYX第一轮)
题目1: POJ 2318 TOYS 题目大意: 给一个有n个挡板的盒子,从左到右空格编号为0...n.有好多玩具,问每个玩具在哪个空格里面. 算法讨论: 直接叉积判断就可以.注意在盒子的边界上面也算 ...
- 线段相交 POJ 2653
// 线段相交 POJ 2653 // 思路:数据比较水,据说n^2也可以过 // 我是每次枚举线段,和最上面的线段比较 // O(n*m) // #include <bits/stdc++.h ...
- 2015南阳CCPC D - Pick The Sticks dp
D - Pick The Sticks Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description The story happened lon ...
- poj 2653 线段与线段相交
Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 11884 Accepted: 4499 D ...
- CDOJ 1218 Pick The Sticks
Pick The Sticks Time Limit: 15000/10000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others ...
- 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 ...
随机推荐
- MySQL的分页
有朋友问: MySQL的分页似乎一直是个问题,有什么优化方法吗?网上看到网上推荐了一些分页方法,但似乎不太可行,你能点评一下吗? 方法1: 直接使用数据库提供的SQL语句 ---语句样式: MySQL ...
- Python win7下 django-admin.py startproject mysite命令没有创建mysite?
解决方案 解决:这个命令在XP下正常(我没试过),我用的win7,无法创建.这属于django的一个bug. 方法是:修改注册表中 HKEY_CLASSES_ROOT/Applications/pyt ...
- Python 命令详解
1. 新建一个 django-project django-admin.py startproject project-name 一个 project 一般为一个项目 2. 新建 app python ...
- Android自定义dialogdemo
很多时候,我们需要自己去定义dialog,目前我们就遇见了这样一个需求,我的想法是自己定义一个dialog,如果有list的话就使用listview,如果有msg的话就使用msg,并且取消和确定按钮也 ...
- awk内置字符串函数 awk 格式化输出
i249 ~ # ps -efl|head -1|awk '$2~/S/{print $2}'Si249 ~ # ps -efl|awk '$2~/S/{print $2}'SSSS printf - ...
- VirtualBox共享文件夹等高级特性
转自: http://blog.csdn.net/longerzone/article/details/32119457 http://www.oschina.net/translate/10-vir ...
- 【Django】Django 文件下载最佳实践
代码: from django.http import StreamingHttpResponse def big_file_download(request): # do something... ...
- 【leetcode】Interleaving String
Interleaving String Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. Fo ...
- vim技巧之快速进入引号删除至右引号前的内容
参考:http://blog.chinaunix.net/uid-23381466-id-88482.html f'l ct' #fX,X可用任何字符,l表示向右移一位,ct'表示删除至引号前di'
- c/c++指针总结[pointer summary]
[本文链接] http://www.cnblogs.com/hellogiser/p/pointer-summary.html 1.指针注意事项 (1). 指针类型字符串不容许修改 char *str ...
