程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> BZOJ 2732([HNOI2012]射箭-半平面交)

BZOJ 2732([HNOI2012]射箭-半平面交)

編輯:C++入門知識

2732: [HNOI2012]射箭
Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 186  Solved: 104
[Submit][Status][Discuss]
Description
沫沫最近在玩一個二維的射箭游戲,如下圖 1 所示,這個游戲中的 x 軸在地面,第一象限中有一些豎直線段作為靶子,任意兩個靶子都沒有公共部分,也不會接觸坐標軸。沫沫控制一個位於(0,0)的弓箭手,可以朝 0 至 90?中的任意角度(不包括 0度和 90度),以任意大小的力量射出帶有穿透能力的光之箭。由於游戲中沒有空氣阻力,並且光之箭沒有箭身,箭的軌跡會是一條標准的拋物線,被軌跡穿過的所有靶子都認為被沫沫射中了,包括那些 只有端點被射中的靶子。這個游戲有多種模式,其中沫沫最喜歡的是闖關模式。在闖關模式中,第一關只有一個靶 子,射中這個靶子即可進入第二關,這時在第一關的基礎上會出現另外一個靶子,若能夠一箭 雙雕射中這兩個靶子便可進入第三關,這時會出現第三個靶子。依此類推,每過一關都會新出 現一個靶子,在第 K 關必須一箭射中前 K 關出現的所有 K 個靶子才能進入第 K+1 關,否則游戲 結束。沫沫花了很多時間在這個游戲上,卻最多只能玩到第七關“七星連珠”,這讓她非常困惑。 於是她設法獲得了每一關出現的靶子的位置,想讓你告訴她,最多能通過多少關

Input
輸入文件第一行是一個正整數N,表示一共有N關。接下來有N行,第i+1行是用空格隔開的三個正整數xi,yi1,yi2(yi1<yi2 ),表示第i關出現的靶子的橫坐標是xi,縱坐標的范圍是從yi1到yi2 。
 輸入保證30%的數據滿足N≤100,50%的數據滿足N≤5000,100%的數據滿足N≤100000且給 出的所有坐標不超過109 。
 

Output

僅包含一個整數,表示最多的通關數。


Sample Input
5

2 8 12
5 4 5
3 8 10
6 2 3
1 3 7

Sample Output
3

HINT

 

\

 


先把方程寫出來,改一改。
然後在坐標系上做半平面交。
[cpp]
#include<cstdio>  
#include<cstring>  
#include<cstdlib>  
#include<cmath>  
#include<iostream>  
#include<algorithm>  
#include<functional>  
#define MAXN (100000+10)  
#define MAXCi (1000000000)  
#define eps 1e-15  
#define For(i,n) for(int i=1;i<=n;i++)  
using namespace std; 
int n; 
struct P 

    double x,y; 
    P(){} 
    P(double _x,double _y):x(_x),y(_y){} 
}p[MAXN*4]; 
struct V 

    double x,y; 
    V(){} 
    V(double _x,double _y):x(_x),y(_y){} 
    V(P a,P b):x(b.x-a.x),y(b.y-a.y){} 
    friend double operator*(V a,V b){return a.x*b.y-a.y*b.x;} 
    friend V operator*(double a,V b){return V(a*b.x,a*b.y);} 
    friend P operator+(P a,V b){return P(a.x+b.x,a.y+b.y);} 
}; 
struct line 

    P p; 
    V v; 
    double ang; 
    int i; 
    line(){} 
    line(double _x,double _y,double _a,double _b,int _i):p(P(_x,_y)),v(V(_a,_b)),i(_i){ang=atan2(v.y,v.x);} 
    bool onleft(P A) 
    { 
        return v*V(p,A)>=0; 
    } 
    bool operator<(const line& l) const 
    { 
        return ang<l.ang; 
    } 
    friend P getinter(line a,line b) 
    { 
        /*
        V u=V(a.p,b.p);
        double t=(a.v*u)/(b.v*a.v);
        return b.p+(t*b.v);
        double s1=V(a.p,b.p+b.v)*a.v;
        double s2=a.v*V(a.p,b.p);
        return b.p+(-s1/(s1+s2))*b.v;
//      V u=V(a.p,b.p);
        */ 
        V u=V(b.p,a.p); 
        double t=(b.v*u)/(a.v*b.v); 
        return a.p+t*a.v;    
         
    } 
}que[MAXN*10],q[MAXN*4]; 
int size=0; 
int half_intersection(line *l,int n) 

    int first=1,last=0; 
    for (int i=1;i<=size;i++) 
    { 
        if (l[i].i>n) continue; 
        if (!last) {q[++last]=l[i];continue;} 
        while (first<last&&!l[i].onleft(p[last-1])) last--; 
        while (first<last&&!l[i].onleft(p[first])) first++; 
        if (fabs(q[last].v*l[i].v)<=eps) 
        { 
            if (q[last].onleft(l[i].p)) q[last]=l[i]; 
        } 
        else q[++last]=l[i]; 
        if (first<last) p[last-1]=getinter(q[last-1],q[last]); 
    } 
    bool flag=1; 
    while (flag) 
    { 
        flag=0; 
        while (first<last&&!q[first].onleft(p[last-1])) last--,flag=1; 
        while (first<last&&!q[last].onleft(p[first])) first++,flag=1; 
    } 
    /*
    p[last]=getinter(q[last],q[first]);
    for (int i=first;i<=last;i++) 
        printf("%lf %lf\n",p[i].x,p[i].y);
    cout<<endl;
    */ 
    return last-first>1; 

void pri(line a,line b) 

    P c=getinter(a,b); 
    printf("%.lf %.lf\n",c.x,c.y); 

int main() 

    freopen("archery.in","r",stdin);     
    freopen("archery.out","w",stdout); 
    cin>>n; 
    que[1]=line(0,0,0,1,0); 
    que[2]=line(-1,0,1,0,0);      
    que[3]=line(0,MAXCi,-1,0,0); 
    que[4]=line(-MAXCi,MAXCi,0,-1,0);size=4; 
//  pri(que[3],que[4]);  
//  size=0;  
    for (int i=1;i<=n;i++) 
    { 
        double x,l,r; 
        scanf("%lf%lf%lf",&x,&l,&r); 
        que[++size]=line(0,l/x,1/x,-1,i); 
        que[++size]=line(0,r/x,-1/x,1,i); 
    } 
    sort(que+1,que+1+size); 
//  cout<<size<<endl;  
//  for (int i=l;i<=r;i++) cout<<halsf_intersection(que,i)<<' ';  
//  cout<<half_intersection(que,50001);  
    int l=0,r=n,Mid=0; 
    while (l<=r) 
    { 
        int mid=(l+r)>>1; 
        if (half_intersection(que,mid)) {Mid=mid;l=mid+1;}else r=mid-1; 
    } 
    cout<<Mid<<endl; 
    return 0; 

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<functional>
#define MAXN (100000+10)
#define MAXCi (1000000000)
#define eps 1e-15
#define For(i,n) for(int i=1;i<=n;i++)
using namespace std;
int n;
struct P
{
 double x,y;
 P(){}
 P(double _x,double _y):x(_x),y(_y){}
}p[MAXN*4];
struct V
{
 double x,y;
 V(){}
 V(double _x,double _y):x(_x),y(_y){}
 V(P a,P b):x(b.x-a.x),y(b.y-a.y){}
 friend double operator*(V a,V b){return a.x*b.y-a.y*b.x;}
 friend V operator*(double a,V b){return V(a*b.x,a*b.y);}
 friend P operator+(P a,V b){return P(a.x+b.x,a.y+b.y);}
};
struct line
{
 P p;
 V v;
 double ang;
 int i;
 line(){}
 line(double _x,double _y,double _a,double _b,int _i):p(P(_x,_y)),v(V(_a,_b)),i(_i){ang=atan2(v.y,v.x);}
 bool onleft(P A)
 {
  return v*V(p,A)>=0;
 }
 bool operator<(const line& l) const
 {
  return ang<l.ang;
 }
 friend P getinter(line a,line b)
 {
  /*
  V u=V(a.p,b.p);
  double t=(a.v*u)/(b.v*a.v);
  return b.p+(t*b.v);
  double s1=V(a.p,b.p+b.v)*a.v;
  double s2=a.v*V(a.p,b.p);
  return b.p+(-s1/(s1+s2))*b.v;
//  V u=V(a.p,b.p);
  */
  V u=V(b.p,a.p);
  double t=(b.v*u)/(a.v*b.v);
  return a.p+t*a.v; 
  
 }
}que[MAXN*10],q[MAXN*4];
int size=0;
int half_intersection(line *l,int n)
{
 int first=1,last=0;
 for (int i=1;i<=size;i++)
 {
  if (l[i].i>n) continue;
  if (!last) {q[++last]=l[i];continue;}
  while (first<last&&!l[i].onleft(p[last-1])) last--;
  while (first<last&&!l[i].onleft(p[first])) first++;
  if (fabs(q[last].v*l[i].v)<=eps)
  {
   if (q[last].onleft(l[i].p)) q[last]=l[i];
  }
  else q[++last]=l[i];
  if (first<last) p[last-1]=getinter(q[last-1],q[last]);
 }
 bool flag=1;
 while (flag)
 {
  flag=0;
  while (first<last&&!q[first].onleft(p[last-1])) last--,flag=1;
  while (first<last&&!q[last].onleft(p[first])) first++,flag=1;
 }
 /*
 p[last]=getinter(q[last],q[first]);
 for (int i=first;i<=last;i++)
  printf("%lf %lf\n",p[i].x,p[i].y);
 cout<<endl;
 */
 return last-first>1;
}
void pri(line a,line b)
{
 P c=getinter(a,b);
 printf("%.lf %.lf\n",c.x,c.y);
}
int main()
{
 freopen("archery.in","r",stdin); 
 freopen("archery.out","w",stdout);
 cin>>n;
 que[1]=line(0,0,0,1,0);
 que[2]=line(-1,0,1,0,0); 
 que[3]=line(0,MAXCi,-1,0,0);
 que[4]=line(-MAXCi,MAXCi,0,-1,0);size=4;
// pri(que[3],que[4]);
// size=0;
 for (int i=1;i<=n;i++)
 {
  double x,l,r;
  scanf("%lf%lf%lf",&x,&l,&r);
  que[++size]=line(0,l/x,1/x,-1,i);
  que[++size]=line(0,r/x,-1/x,1,i);
 }
 sort(que+1,que+1+size);
// cout<<size<<endl;
// for (int i=l;i<=r;i++) cout<<halsf_intersection(que,i)<<' ';
// cout<<half_intersection(que,50001);
 int l=0,r=n,Mid=0;
 while (l<=r)
 {
  int mid=(l+r)>>1;
  if (half_intersection(que,mid)) {Mid=mid;l=mid+1;}else r=mid-1;
 }
 cout<<Mid<<endl;
 return 0;
}

 


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved