在一个广场上有一排沿着东西方向排列的石柱子,阳光从东边以一定的倾角射来(平行光)。有的柱子可能被在他东边的高大的柱子的影子给完全遮挡住了。现在你要解决的问题是求出有多少柱子是没有被完全遮挡住的。

假设每个石柱子是一根细棒,而且都垂直于地面摆放。

Input

输入包含多组数据。每组数据第一行是一个整数N(0<N100000),表示柱子的个数。N=0代表输入结束。接下来有N行,每行是两个整数,分别给出每根柱子的水平位置X和高度HX越大,表示越在西边,0X10000000,0<H10000000保证不会有两根柱子在同一个X坐标上)。最后有一行,以分数的形式给出太阳光与地面的夹角的正切值T/A(1A,T10)。

Output

对每组数据,输出包含所求数目的一行。

Sample input and output

Sample InputSample Output
4
0 3
3 1
2 2
1 1
1/1
0
2

Hint

输入数据很多,请用scanf代替cin

Source

电子科技大学第六届ACM程序设计大赛 初赛
 
 
这道题是一道比较容易的题,但一开始我还以为要用线段树,后来发现没法写。。。
后来一想,发现只要一直维护一个影子的最长坐标就可以过了。
 
具体做法是先对坐标排序,然后算出最靠左的柱子的影子最右坐标,再算下一个柱子影子的最右坐标,这时候比较这两个坐标,如果第一个大于等于第二个,则二号柱子被挡住,否则二号柱子不被挡住,然后取这两者的 大者,对第三柱子计算,然后再取大者,对第四柱子计算·········
Hit:要用scanf读入,不能用cin。。。。
#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
long x[100002]={},h[100003]={};
void quick(long j,long k)
{
    long m,n,c,v;
    n=j;m=k;c=x[(j+k)/2];
    do{
        while (x[n]<c) n++;
        while (x[m]>c) m--;
        if (n<=m){
            v=x[n];x[n]=x[m];x[m]=v;
            v=h[n];h[n]=h[m];h[m]=v;
            n++;m--;
        }
    }while (n<=m);
    if (n<k) quick(n,k);
    if (m>j) quick(j,m);
}
int main()
{
    long l;
    scanf("%ld",&l);
    while (l!=0){
        memset(x,0,sizeof(x));
        memset(h,0,sizeof(h));
        int j;
        for (j=1;j<=l;j++)
            scanf("%ld %ld",&x[j],&h[j]);
        int A,T;
        scanf("%d/%d",&T,&A);
        quick(1,l);
        long num=0;
        double g=0,f;
        for (j=1;j<=l;j++){
            if (g<(f=x[j]+h[j]*1.0*A/T)){
                num++;
                g=f;
            }
        }
        cout<<num<<endl;
        scanf("%ld",&l);
    }
    return 0;
}