【Gym - 102428D】Dazzling stars(计算几何)

Gym - 102428D

题意

平面上有许多点,每个点有权值,问是否存在一条直线,令这条直线按照某个方向移动,使其经过的点权值不下降,且能经过所有点。

题解

算是个结论题。每个点向权值比它小的所有点连成向量,将所有向量的起点移动到原点,如果所有向量都位于某条过原点的直线的一侧,则所求直线存在。将所有向量根据角度排序,判断是否有相邻向量夹角大于180度即可。
(代码写得比较乱,没用计算几何模板)

#include
using namespace std;
const int N=2000;
const double pi=acos(-1);

int x[N],y[N],b[N];
vector<double>u;
double cal(int x,int y){
	if(x==0)return y>0?pi/2:-pi/2;
	if(y==0)return x>0?0:pi;
	double ans=atan(double(y)/x);
	if(x>0)return ans;
	return ans+pi;
}
bool check(){
	if(u.size()<2)return true;
	double y=u.back()-pi*2;
	for(auto x:u){
		if(x-y+1e-9>=pi)return true;
		y=x;
	}
	return false;
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>x[i]>>y[i]>>b[i];
		for(int j=0;j<i;j++){
			if(b[i]<b[j])u.push_back(cal(x[i]-x[j],y[i]-y[j]));
			else if(b[i]>b[j])u.push_back(cal(x[j]-x[i],y[j]-y[i]));
		}
	}
	sort(u.begin(),u.end());
	if(check())cout<<"Y\n";
	else cout<<"N\n";
	return 0;
}

你可能感兴趣的:(计算几何)