Pick-up sticks
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 12861   Accepted: 4847

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


还是判断线段相交
注意两条线段共线的情况,用点积判断
太诡异从后往前暴力判断能过,用一个栈维护当前没有覆盖的线段也能过
但是最坏复杂度都是N^2啊???
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=1e5+;
const double eps=1e-;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
inline int sgn(double x){
if(abs(x)<eps) return ;
else return x<?-:;
}
struct Vector{
double x,y;
Vector(double a=,double b=):x(a),y(b){}
bool operator <(const Vector &a)const{
return x<a.x||(x==a.x&&y<a.y);
}
void print(){
printf("%lf %lf\n",x,y);
}
};
typedef Vector Point;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator *(Vector a,double b){return Vector(a.x*b,a.y*b);}
Vector operator /(Vector a,double b){return Vector(a.x/b,a.y/b);}
bool operator ==(Vector a,Vector b){return sgn(a.x-b.x)==&&sgn(a.y-b.y)==;} double Cross(Vector a,Vector b){
return a.x*b.y-a.y*b.x;
}
double Dot(Vector a,Vector b){
return a.x*b.x+a.y*b.y;
}
double DisPP(Point a,Point b){
Point t=a-b;
return sqrt(t.x*t.x+t.y*t.y);
}
struct Line{
Point s,t;
Line(){}
Line(Point p,Point v):s(p),t(v){}
}l[N];
bool isLSI(Line l1,Line l2){
Vector v=l1.t-l1.s,u=l2.s-l1.s,w=l2.t-l1.s;
return sgn(Cross(v,u))!=sgn(Cross(v,w));
}
bool isSSI(Line l1,Line l2){
Vector v1=l1.t-l1.s,v2=l2.t-l2.s;
if(sgn(Cross(v1,v2))==){
int flag=;
Vector u=l2.s-l1.s,w=l2.t-l1.s;
if(sgn(Dot(u,w))<) flag=;
u=l2.s-l1.t,w=l2.t-l1.t;
if(sgn(Dot(u,w))<) flag=;
return flag;
}
else return isLSI(l1,l2)&&isLSI(l2,l1);
} int n;
bool vis[N];
double x,y,x2,y2;
int main(int argc, const char * argv[]) {
while(true){
memset(vis,,sizeof(vis));
n=read(); if(n==) break;
for(int i=;i<=n;i++){
scanf("%lf%lf%lf%lf",&x,&y,&x2,&y2);
l[i]=Line(Point(x,y),Point(x2,y2));
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++) if(isSSI(l[j],l[i])){vis[i]=;break;}
}
printf("Top sticks: ");
int fir=;
for(int i=;i<=n;i++) if(!vis[i]){
if(fir) printf("%d",i),fir=;
else printf(", %d",i);
}
puts(".");
}
return ;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=1e5+;
const double eps=1e-;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
inline int sgn(double x){
if(abs(x)<eps) return ;
else return x<?-:;
}
struct Vector{
double x,y;
Vector(double a=,double b=):x(a),y(b){}
bool operator <(const Vector &a)const{
return x<a.x||(x==a.x&&y<a.y);
}
void print(){
printf("%lf %lf\n",x,y);
}
};
typedef Vector Point;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator *(Vector a,double b){return Vector(a.x*b,a.y*b);}
Vector operator /(Vector a,double b){return Vector(a.x/b,a.y/b);}
bool operator ==(Vector a,Vector b){return sgn(a.x-b.x)==&&sgn(a.y-b.y)==;} double Cross(Vector a,Vector b){
return a.x*b.y-a.y*b.x;
}
double Dot(Vector a,Vector b){
return a.x*b.x+a.y*b.y;
}
double DisPP(Point a,Point b){
Point t=a-b;
return sqrt(t.x*t.x+t.y*t.y);
}
struct Line{
Point s,t;
Line(){}
Line(Point p,Point v):s(p),t(v){}
}l[N];
bool isLSI(Line l1,Line l2){
Vector v=l1.t-l1.s,u=l2.s-l1.s,w=l2.t-l1.s;
return sgn(Cross(v,u))!=sgn(Cross(v,w));
}
bool isSSI(Line l1,Line l2){
Vector v1=l1.t-l1.s,v2=l2.t-l2.s;
if(sgn(Cross(v1,v2))==){
int flag=;
Vector u=l2.s-l1.s,w=l2.t-l1.s;
if(sgn(Dot(u,w))<) flag=;
u=l2.s-l1.t,w=l2.t-l1.t;
if(sgn(Dot(u,w))<) flag=;
return flag;
}
else return isLSI(l1,l2)&&isLSI(l2,l1);
} int n,st[N],top;
inline void del(int p){
for(int i=p;i<=top;i++) st[i]=st[i+];top--;
}
double x,y,x2,y2;
int main(int argc, const char * argv[]) {
while(true){
top=;
n=read(); if(n==) break;
for(int i=;i<=n;i++){
scanf("%lf%lf%lf%lf",&x,&y,&x2,&y2);
l[i]=Line(Point(x,y),Point(x2,y2));
for(int j=;j<=top;j++) if(isSSI(l[st[j]],l[i])) del(j),j--;
st[++top]=i;
}
printf("Top sticks: %d",st[]);
for(int i=;i<=top;i++) printf(", %d",st[i]);
puts(".");
}
return ;
}

POJ 2653 Pick-up sticks [线段相交 迷之暴力]的更多相关文章

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

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

  2. POJ 2653 Pick-up sticks(线段相交)

    题意:给定n个木棍依次放下,要求最终判断没被覆盖的木棍是哪些. 思路:快速排斥以及跨立实验可以判断线段相交. #include<algorithm> #include<cstdio& ...

  3. POJ 1066 Treasure Hunt (线段相交)

    题意:给你一个100*100的正方形,再给你n条线(墙),保证线段一定在正方形内且端点在正方形边界(外墙),最后给你一个正方形内的点(保证不再墙上) 告诉你墙之间(包括外墙)围成了一些小房间,在小房间 ...

  4. POJ 1410 Intersection --几何,线段相交

    题意: 给一条线段,和一个矩形,问线段是否与矩形相交或在矩形内. 解法: 判断是否在矩形内,如果不在,判断与四条边是否相交即可.这题让我发现自己的线段相交函数有错误的地方,原来我写的线段相交函数就是单 ...

  5. POJ 1269 Intersecting Lines(线段相交,水题)

    id=1269" rel="nofollow">Intersecting Lines 大意:给你两条直线的坐标,推断两条直线是否共线.平行.相交.若相交.求出交点. ...

  6. POJ 1066 Treasure Hunt【线段相交】

    思路:枚举四边墙的门的中点,与终点连成一条线段,判断与其相交的线段的个数.最小的加一即为答案. 我是傻逼,一个数组越界调了两个小时. #include<stdio.h> #include& ...

  7. poj 1556 (Dijkstra + Geometry 线段相交)

    链接:http://poj.org/problem?id=1556 The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

  8. POJ 3304 Segments[直线与线段相交]

    Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13514   Accepted: 4331 Descrip ...

  9. POJ 1408 Fishnet【枚举+线段相交+叉积求面积】

    题目: http://poj.org/problem?id=1408 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

随机推荐

  1. [UWP]使用Reveal

    1. 前言 之前在 如何使用Fluent Design System 这篇文章里已经简单介绍过Reveal的用法,这篇再详细介绍其它内容. 2. 自定义RevealButtonStyle 我觉得常用I ...

  2. [国嵌攻略][149][Yaffs2文件系统应用]

    嵌入式系统自启动 MTD技术通过把Nand FLash划分成bootloader分区,Linux kernel分区和file system分区来达到自启动的效果. 配置和编译内核 1.配置Linux内 ...

  3. 遍历数组中的元素(含es6方法)

    假如有这样一个数组.arr = [12,34,45,46,36,58,36,59],现在要遍历该数组. 方法1:以前我们可能会这样做: for(var i=0;i<arr.length;i++) ...

  4. 猜随机数(控制台输入,字符串转int)

    package com.hanqi.suijishu; import java .util.Random; // main方法类 专门用来运行方法 public class Main { public ...

  5. 基于FPGA的HDMI高清显示接口驱动

    HDMI是(High Definition Multimedia Interface)的缩写,意思是高清晰度多媒体接口,是一种数字化视频/音频接口技术,适合影像传输的专用型数字化接口,可同时传送音频和 ...

  6. 借助 Vue 来构建单页面应用

    原文: https://github.com/MeCKodo/vue-tutorial 主题 Vue.js (1/2)Vue构建单页应用最佳实战 前言 我们将会选择使用一些vue周边的库 1.使用no ...

  7. phthon网络编程

    软件开发架构 既然谈起网络编程,就得说说软件开发的架构: c/s架构 C/S结构软件(即客户机/服务器模式)分为客户机和服务器两层,客户机不是毫无运算能力的输入.输出设备,而是具有了一定的数据处理和数 ...

  8. 辩证看待 iostat

    前言 经常做系统分析会接触到很多有用的工具,比如 iostat,它是用来分析磁盘性能.系统 I/O 的利器. 本文将重点介绍 iostat 命令的使用,并分析容易引起误解的几个指标. iostat i ...

  9. c# winform 类似android toast消息功能

    先看下效果: 支持动画,支持声音,支持定时自动关闭 使用方法: var notifycation = new Notification("My Notification", &qu ...

  10. Angular19 自定义表单控件

    1 需求 当开发者需要一个特定的表单控件时就需要自己开发一个和默认提供的表单控件用法相似的控件来作为表单控件:自定义的表单控件必须考虑模型和视图之间的数据怎么进行交互 2 官方文档 -> 点击前 ...