POJ 2653 Pick-up sticks

 

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

这道题目,我直接用暴力过的,刚开始交的C++一直超时,改成G++后就可以过

题意很好理解,就是让你找两线段是否相交,如果相交,那么编号大的一定在编号小的上面,就把编号小的标记就可以了

代码如下:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int maxn=1002;
const int N=100002;

struct point
{
   double x,y;
};

struct Seg
{
   point a,b;
}s[N];

bool flag[N];
int a[maxn];

//重载最大值、最小值计算函数
double min(double x,double y)
{return x<y?x:y;}
double max(double x,double y)
{return x>y?x:y;}

//判断double型的正数、负数和0,分别相应的返回1、-1和0
int dblcmp(double x)
{
   if(x==0) return 0;
   return (x>0)?1:-1;
}
//计算叉积
double det(double x1,double y1,double x2,double y2)
{return x1*y2-x2*y1;}

//计算a,b,c三点的叉积,判断a,b,c三点的位置关系
double cross(point a,point b,point c)
{return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);}

//计算两点间的最短距离
double dist(point a,point b)
{return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}

//判断线段是否相交,相交为true,不相交为false
bool segcross(point a,point b,point c,point d)
{
   int d1,d2,d3,d4;
   d1=dblcmp(cross(a,b,c));
   d2=dblcmp(cross(a,b,d));
   d3=dblcmp(cross(c,d,a));
   d4=dblcmp(cross(c,d,b));
   if((d1^d2)==-2&&(d3^d4)==-2) return true;
   return false;
}

int main()
{
   int n;
   while(scanf("%d",&n),n)
   {
      memset(flag,0,sizeof(flag));
      for(int i=0;i<n;i++)
         scanf("%lf%lf%lf%lf",&s[i].a.x,&s[i].a.y,&s[i].b.x,&s[i].b.y);
      for(int i=0;i<n-1;i++)
         for(int j=i+1;j<n;j++)
            if(!flag[i]&&segcross(s[i].a,s[i].b,s[j].a,s[j].b))
            {flag[i]=1;break;}
      cout<<"Top sticks: ";
      int k=0;
      for(int i=0;i<n;i++)
         if(!flag[i])
            a[k++]=i+1;
      for(int i=0;i<k-1;i++)
         printf("%d, ",a[i]);
      printf("%d.\n",a[k-1]);
   }
  
   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值