运用数学知识传送门 飞跃:在平面中,一个点绕任意点旋转θ度后的点的坐标
链接: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
备注:
n≤1000000,T≤10,0≤|xi|,|yi|≤109
思路找出边界的四个点对比
在运用数学知识找四个点
#include <bits/stdc++.h>
#define maxn 2005555
typedef long long ll;
using namespace std;
struct light
{
ll x;
ll y;
}
a[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
ll t,n;
cin >> t;
while(t--)
{
ll mix = 1e17;
ll mx = -1e17;
ll miy = 1e17;
ll my = -1e17;
ll flag = 0;
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i].x >> a[i].y;
mx = max(mx,a[i].x);
my = max(my,a[i].y);
mix = min(mix,a[i].x);
miy = min(miy,a[i].y);
}
for(int i = 1; i <= n; i ++)
{
if(mix == a[i].x && miy == a[i].y)
{
flag = 1;
}
if(mx == a[i].x && my == a[i].y)
{
flag = 1;
}
if(mx == a[i].x && miy == a[i].y)
{
flag = 1;
}
if(mix == a[i].x && my == a[i].y)
{
flag = 1;
}
}
mix = 1e17;
mx = -1e17;
miy = 1e17;
my = -1e17;
for(int i = 1; i <= n; i ++)
{
ll tx=a[i].x,ty=a[i].y;
a[i].x = tx - ty;
a[i].y = tx + ty;
mx = max(mx,a[i].x);
my = max(my,a[i].y);
mix = min(mix,a[i].x);
miy = min(miy,a[i].y);
}
for(int i = 1; i <= n; i ++)
{
if(mix == a[i].x && miy == a[i].y)
{
flag = 1;
}
if(mx == a[i].x && my == a[i].y)
{
flag = 1;
}
if(mx == a[i].x && miy == a[i].y)
{
flag = 1;
}
if(mix == a[i].x && my == a[i].y)
{
flag = 1;
}
}
if(flag == 1)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
return 0;
}