• _bzoj1007 [HNOI2008]水平可见直线【单调栈】


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1007

    按斜率排序,去掉斜率相同时,截距较小的直线(即只保留该斜率下截距最大的直线)。若当前直线与栈顶直线的交点的x坐标<=栈顶直线与栈顶第二条直线的交点的x左边,则pop,直到前者大于后者为止,因为若小于等于,那么栈顶这条直线一定被覆盖。

    #include <cstdio>
    #include <algorithm>
    
    const int maxn = 50005;
    
    int n, tem_n, top, ori_n;
    char book[maxn];
    struct line {
    	long long k, b;
    	int id;
    } a[maxn], stk[maxn];
    struct point {
    	double x, y;
    };
    
    bool cmp(const line & aa, const line & ss) {
    	if (aa.k == ss.k) {
    		return aa.b > ss.b;
    	}
    	return aa.k < ss.k;
    }
    
    int main(void) {
    	scanf("%d", &n);
    	for (int i = 0; i < n; ++i) {
    		scanf("%lld%lld", &a[i].k, &a[i].b);
    		a[i].id = i;
    	}
    	std::sort(a, a + n, cmp);
    	tem_n = 1;
    	for (int i = 1; i < n; ++i) {
    		if (a[i].k != a[i - 1].k) {
    			a[tem_n++] = a[i];
    		}
    	}
    	ori_n = n;
    	n = tem_n;
    	
    	for (int i = 0; i < n; ++i) {
    		while (top > 1 && (stk[top - 1].b - a[i].b) * (stk[top - 1].k - stk[top - 2].k) <= (stk[top - 2].b - stk[top - 1].b) * (a[i].k - stk[top - 1].k)) {
    			--top;
    		}
    		stk[top++] = a[i];
    	}
    	for (int i = 0; i < top; ++i) {
    		book[stk[i].id] = 1;
    	}
    	for (int i = 0; i < ori_n; ++i) {
    		if (book[i]) {
    			printf("%d ", i + 1);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    数组
    js--函数
    for循环
    运算符
    js 正则表达式
    js DOM节点
    js 字符串
    js 函数
    2018-12-26 课堂笔记 for循环
    2018-12-25 课堂笔记 js
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6180815.html
Copyright © 2020-2023  润新知