bzoj 1007

/*
8
-6 -12
-2.5 -2.5
-1.333 0
-0.4 0.8
6 24
6 25
0 100
0 101
*/
//你的答案錯的
//错的原因在于你sort的时候应该是sort(stack,stack+top+1,com2)然而你写成了sort(stack,stack+top,com2)

其他关键就是从反向思考当最后结束时那些线是什么样你就会发现其实那些线一定是一堆包络线不是上凸就是下凹这样用栈就阔以解决问题了就像优先队列的题目一样最开始我想的是李超线段树不过那样搞得话就大才小用了李超线段树是在线的而这个题目只要求离线所以呵呵。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct linee{
	double k, b ;
	int num;
}line[50001];
struct nodee{
	linee c;
	double x, y;
}stack[50001];
bool com1(linee a, linee b)
{
	if (fabs(a.k-b.k)<1e-8)
	{
		if (a.b>b.b)
			return true;
		return false;
	}
	if (a.k < b.k)
	{
		return true;
	}

	if (a.k > b.k)
		return false;
}
bool com2(nodee a, nodee b)
{
	if (a.c.num == b.c.num)
		return false;
	if (a.c.num < b.c.num)
		return true;
	if (a.c.num>b.c.num)
	   return false;
}
double jiao(linee a, linee b)
{
	double k = (b.b - a.b) / (a.k - b.k);
	return k;
}
int top = -1;
int n;
int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		double k, b;
		scanf("%lf%lf", &k, &b);
		//cout << k << " " << b << endl;
		line[i].k = k;
		line[i].b = b;
		line[i].num = i;
	}
	sort(line, line + n, com1);
	stack[++top].c = line[0];
	for (int i = 1; i < n; i++)
	{
		if (fabs(stack[top].c.k - line[i].k)<1e-8)
		{
			continue;
		}
		if (top == 0)
		{
			stack[++top].c = line[i];
		}
		else
		{
			while (top>0&&jiao(line[i],stack[top].c)<=jiao(stack[top].c,stack[top-1].c))
			{
				top--;
			}
			stack[++top].c = line[i];
		}
	}
	sort(stack, stack + top+1, com2);
	for (int i = 0; i <= top; i++)
	{
			printf("%d ", stack[i].c.num + 1);
	}
	return 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值