码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 2967 Colorful Rainbows 【Stack】

时间:2015-03-29 20:49:28      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:

解决此题方法类似于凸包,先把所有直线按照斜率a由小到大排序
斜率相同取b较大的,扔掉b小的 (可以在遍历的时候忽视)。
于是所有直线斜率不同。 准备一个栈 (手动模拟), 栈里面存放上一次能看到的“最上面”的直线以及这条直线能看到的范围x (x值右边的部分可以被看到)。 初始时,把斜率最小的直线入栈,并记录x值为-inf。然后对第i条直线, 所做的是用第i条直线和栈顶直线求交点x,如果这个x值不大于栈顶的x值, 则把栈顶元素弹出,继续求交,否则退出。
这种判断操作直到栈为空, 或者当前栈顶的x值大于栈顶的x值。然后把第i条直线入栈,
继续,看后面的直线。最后栈中的直线数就是能看到的。 这种做法类似于凸包的方法,除去排序外,每条直线至多出入栈一次 复杂度O(n)。总复杂度是O(nlogn)。

Source Code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-8         ;
const int N = 210               ;
const int M = 1100011*2         ;
const ll P = 10000000097ll      ;
const int MAXN = 10900000       ;
const double MINN = -999999999.9;

int n;

struct Line{
    double a, b;
}line[5001];

struct Point{
    int ID;
    double x;   //Crossover point
}point[5001];

bool cmp (Line a , Line b){
    if(a.a != b.a)  return a.a < b.a ;
    return a.b > b.b;
}

int main(){
    int i, j, t, k, u, v, numCase = 0;
    cin >> t;
    while (t--){
        int sum = 0;
        cin >> n;
        for (i = 0; i < n; ++i) {
            cin >> line[i].a >> line[i].b;
        }
        sort (line , line + n, cmp);

        point[sum].ID = 0;
        point[sum].x = MINN;

        for (i = 1; i < n; ++i) {
            if (Abs (line[i].a - line[point[sum].ID].a) < eps)    continue; //Equal slope will be ignored
            for (;;) {
                if (sum < 0) {
                    ++sum;
                    point[sum].ID = i;
                    point[sum].x = MINN;
                    break;
                }
                double x = (line[point[sum].ID].b - line[i].b) / (line[i].a - line[point[sum].ID].a);
                if (point[sum].x + eps > x) {
                    --sum;
                } else {
                    ++sum;
                    point[sum].ID = i;
                    point[sum].x = x;
                    break;
                }
            }
        }
        printf("%d\n", 1 + sum);
     }

     return 0 ;
}

 

ZOJ 2967 Colorful Rainbows 【Stack】

标签:

原文地址:http://www.cnblogs.com/wushuaiyi/p/4376157.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!