当前位置: 首页 > 工具软件 > Rainbows! > 使用案例 >

Colorful Rainbows ZOJ - 2967

马德厚
2023-12-01

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2967

首先斜率相同去个重 然后单调栈维护每条直线和之前可见直线的交点及自身斜率和截距 对于新加直线 看于栈顶直线的交点位置即可

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <cmath>
using namespace std;
const double eps=1e-10;
const int maxn=8e3+10;

struct node
{
	double k,b,p;
};

stack <node> stk;
node line[maxn];
int n;

bool cmp(node n1,node n2)
{
	if(fabs(n1.k-n2.k)<eps) return n1.b>n2.b;
	else return n1.k<n2.k;
}

int main()
{
	node cur,tmp;
	double pos;
	int t,i,j;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		for(i=1;i<=n;i++){
			scanf("%lf%lf",&line[i].k,&line[i].b);
		}
		sort(line+1,line+n+1,cmp);
		j=0;
		for(i=1;i<=n;i++){
			if(j==0||fabs(line[j].k-line[i].k)>eps){
				line[++j]=line[i];
			}
		}
		n=j;
		if(n==1){
			printf("1\n");
			continue;
		}
		while(!stk.empty()) stk.pop();
		tmp.k=line[1].k,tmp.b=line[1].b,tmp.p=0;
		stk.push(tmp);
		tmp.k=line[2].k,tmp.b=line[2].b,tmp.p=(line[2].b-line[1].b)/(line[1].k-line[2].k);
		stk.push(tmp);
		for(i=3;i<=n;i++){
			while(stk.size()>1){
				cur=stk.top();
				pos=(line[i].b-cur.b)/(cur.k-line[i].k);
				if(cur.p>pos||fabs(cur.p-pos)<eps) stk.pop();
				else{
					tmp.k=line[i].k,tmp.b=line[i].b,tmp.p=(line[i].b-cur.b)/(cur.k-line[i].k);
					stk.push(tmp);
					break;
				}
			}
			if(stk.size()==1){
				tmp.k=line[i].k,tmp.b=line[i].b,tmp.p=(line[i].b-line[1].b)/(line[1].k-line[i].k);
				stk.push(tmp);
			}
		} 
		printf("%d\n",stk.size());
	}
	return 0;
}

/*
1
3
-2 -2
-1 -1
-0.5 -0.5
*/

 

 类似资料:

相关阅读

相关文章

相关问答