ZOJ 3967 Colorful Rainbows --栈的应用

题意:给出n条y=ai*x+bi的直线。对于这些直线,如果存在x使得该直线y大于其他任意一直线,那么这条直线可以被看见,问有多少条直线可以被看见。

做法什么的不讲了,参见:http://blog.csdn.net/ten_three/article/details/12289427  以及  http://blog.sina.com.cn/s/blog_7eee8bf3010136d8.html

利用了堆栈来做,总体复杂度O(nlogn)

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define N 5006

struct node
{
    double x,y;
}p[N],line[N];
node stk[N];

int cmp(node ka,node kb)
{
    if(ka.x == kb.x)
        return ka.y < kb.y;
    return ka.x < kb.x;
}

double calc(node ka,node kb)
{
    double res = (ka.y-kb.y)*1.0/(kb.x-ka.x);
    return res;
}

int main()
{
    int t,m,n,k;
    double now,pre;
    int i,j;
    int tail;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        sort(p,p+n,cmp);
        k = 0;
        for(i=0;i<n-1;i++)
        {
            if(p[i].x != p[i+1].x)
                line[k++] = p[i];
        }
        line[k++] = p[n-1];
        if(k < 2)
        {
            printf("%d
",k);
            continue;
        }
        tail = 0;
        stk[tail++] = line[0];
        stk[tail++] = line[1];
        pre = calc(stk[1],stk[0]);
        int ans = 2;
        for(i=2;i<k;i++)
        {
            now = calc(line[i],stk[tail-1]);
            while(now <= pre)
            {
                tail--;
                if(tail >= 2)
                {
                    pre = calc(stk[tail-1],stk[tail-2]);
                    now = calc(line[i],stk[tail-1]);
                }
                else
                {
                    now = calc(line[i],stk[tail-1]);
                    break;
                }
            }
            stk[tail++] = line[i];
            pre = now;
        }
        printf("%d
",tail);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/whatbeg/p/3852433.html