(2021 ICPC)亚洲区域赛(昆明)I.Mr. Main and Windmills

题目链接:https://ac.nowcoder.com/acm/contest/12548/I

分析

直线用 y = kx + b 来存,直接算交点看是否在线段上,然后根据交点和起点的距离排序即可。
注意如果这样存直线,要特判斜率不存在的情况。
还要注意计算公式,比赛中因为公式抄错就没过,后来检查了半天才发现。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long double ld;

int n,q;
const ld eps = 1e-6;
const ld INF = 1e12+5;

struct point{
    
    
	ld x,y;
}p[1005],s,t;

struct line{
    
    
	ld k,b;
};

vector<point> v;

point getp(line l1, line l2)
{
    
    
	point res;
	res.x = (l2.b - l1.b) / (l1.k - l2.k);
	res.y = l1.k * res.x + l1.b;
	return res;
}

ld getdis(point a,point b)
{
    
    
	ld res = sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
	return res;
}

bool check(point a)
{
    
    
	if(fabs(getdis(a, s) + getdis(a, t) - getdis(s, t)) < eps && getdis(a, s) >= eps && getdis(a, t) >= eps) return true;
	return false;
}

bool cmp(point a,point b)
{
    
    
	return getdis(a, s) < getdis(b, s);
}

int main()
{
    
    
	int T = 1;
	//scanf("%d",&T);
	while(T--)
	{
    
    
		scanf("%d%d",&n,&q);
		scanf("%Lf%Lf%Lf%Lf",&s.x,&s.y,&t.x,&t.y);
		for(int i=1;i<=n;i++)
		{
    
    
			scanf("%Lf%Lf",&p[i].x,&p[i].y);
		}
		
		line l1;
		if(fabs(s.x-t.x) < eps) l1.k = INF, l1.b = s.x;
		else
		{
    
    
			l1.k = (t.y - s.y) / (t.x - s.x);
			l1.b = t.y - l1.k * t.x;
		}
		
		for(int Q=1;Q<=q;Q++)
		{
    
    
			v.clear();
			int x,k;
			scanf("%d%d",&x,&k);
			line l2;
			for(int i=1;i<=n;i++)
			{
    
    
				point t;
				if(i == x) continue;
				if(fabs(p[i].x-p[x].x) < eps)
				{
    
    
					if(fabs(l1.k-INF) < eps) continue;
					t.x = p[i].x;
					t.y = l1.k * t.x + l1.b;
				}
				else
				{
    
    
					l2.k = (p[i].y - p[x].y) / (p[i].x - p[x].x);
					l2.b = p[i].y - l2.k * p[i].x;
					if(fabs(l1.k-INF) < eps)
					{
    
    
						t.x = l1.b;
						t.y = l2.k * t.x + l2.b;
					}
					else if(fabs(l1.k-l2.k) < eps) continue;
					else t = getp(l1, l2);
				}
				
				if(check(t)) v.push_back(t);
			}
			sort(v.begin(), v.end(), cmp);
			//for(int i=0;i<v.size();i++) printf("---  %.6Lf %.6Lf\n",v[i].x,v[i].y);
			if(v.size() >= k) printf("%.10Lf %.10Lf\n",v[k - 1].x,v[k - 1].y);
			else printf("-1\n");
		}
		
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Sankkl1/article/details/115431845