牛客网挑战赛21 A灯塔

链接:https://www.nowcoder.com/acm/contest/159/A
来源:牛客网
 

Z市是一座港口城市,来来往往的船只依靠灯塔指引方向。
在海平面上,存在n个灯塔。每个灯塔可以照亮以它的中心点为中心的90°范围。特別地, 由于特殊限制,每个灯塔照亮范围的角的两条边必须要么与坐标轴平行要么与坐标轴成45°。 由于经费限制,Z市的灯塔只能被点亮一座。你需要求出在这种情况下,是否存在一座灯塔能够照亮Z市的所有灯塔。

输入描述:

第一行一个整数T,表示数据组数。
对于每组数据,第一行一个整数n,表示灯塔的数量。
接下来n行,每行两个整数xi,yi,表示第i座灯塔的坐标点。

输出描述:

如果存在一座灯塔能够照亮Z市的所有灯塔则输出Yes,否则输出No(区分大小写)。

示例1

输入

复制

2
4
1 1
1 2
2 1
2 2
5
4 7
0 4
7 3
3 0
3 4

输出

复制

Yes
No

这个题是一个思维题,想到方法就好做了。

我的方法是通过边来找点,这样就会有八个点,完了遍历一边就好了。有个关键点就是要读懂那个角度,

完了给大家看一下代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>

using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
struct node{
	int x,y;
};
node a[maxn];
node b[maxn];
node c[maxn];
node d[maxn];
int t;
int n;
bool cmp(node p,node q){
	return p.x>q.x;
}
bool cmp1(node p,node q){
	return p.y>q.y;
}
bool cmp2(node p,node q){
	return p.y-p.x>q.y-q.x;
}
bool cmp3(node p,node q){
	return p.x+p.y>q.y+q.x;
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>a[i].x>>a[i].y;
			b[i].x = a[i].x;
			b[i].y = a[i].y;
			c[i].x = a[i].x;
			c[i].y = a[i].y;
			d[i].x = a[i].x;
			d[i].y = a[i].y;
		}
		sort(a,a+n,cmp);
		sort(b,b+n,cmp1);
		sort(c,c+n,cmp2);
		sort(d,d+n,cmp3);
		int flag =0;
	//	cout<<d[0].x<<"---"<<d[0].y<<endl;
	//	cout<<d[n-1].x<<"..."<<d[n-1].y<<endl;
	//	cout<<c[0].x<<",,,"<<c[0].y<<endl;
	//	cout<<c[n-1].x<<"+++"<<c[n-1].y<<endl;
		int t1 = d[0].x+d[0].y;
		int t2 = c[0].y-c[0].x;
		int t3 = d[n-1].x+d[n-1].y;
		int t4 = c[n-1].y-c[n-1].x;
		double y1 = double(t1+t2)/2;
		double x1 = double(t1-t2)/2;
		double y2 = double(t1+t4)/2;
		double x2 = double(t1-t4)/2;
		double y3 = double(t3+t2)/2;
		double x3 = double(t3-t2)/2;
		double y4 = double(t3+t4)/2;
		double x4 = double(t3-t4)/2;
	//	cout<<x1<<"---"<<y1<<endl;
	//	cout<<x2<<"----"<<y2<<endl;
	//	cout<<x3<<"-----"<<y3<<endl;
	//	cout<<x4<<"------"<<y4<<endl;
	//cout<<a[0].x<<"---"<<b[0].y<<endl;
	//cout<<a[0].x<<"----"<<b[n-1].y<<endl;
	//cout<<a[n-1].x<<"-----"<<b[0].y<<endl;
	//cout<<a[n-1].x<<"------"<<b[n-1].y<<endl;
		for(int i=0;i<n;i++){
			if( (a[i].x==a[0].x&&a[i].y==b[0].y) || (a[i].x==a[0].x&&a[i].y == b[n-1].y) || (a[i].x==a[n-1].x&&a[i].y==b[0].y) || (a[i].x==a[n-1].x&&a[i].y==b[n-1].y) || (a[i].x==x1&&a[i].y==y1) || (a[i].x==x2&&a[i].y ==y2) || (a[i].x==x3&&a[i].y==y3) || (a[i].x==x4&&a[i].y==y4)){
				cout<<"Yes"<<endl;
				flag = 1;
				break;
			}
		}
		if(flag==0)cout<<"No"<<endl;
	}
 	return 0;
}

好好学习,记录美好生活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值