持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
三条线
题目描述
农夫约翰想用他购买的新监视系统监视他的 N 头奶牛。
第 i头奶牛位于具有整数坐标的位置 (xi,yi)。
没有两头奶牛占据相同的位置。
约翰的监视系统包含三个特殊的摄像头,每个摄像头都能够沿垂直或水平线观察一条线上所有的奶牛。
请确定约翰是否可以通过合理设置三个摄像头的摆放位置,以便他可以监视所有 N 头奶牛。
也就是说,请确定是否可以通过三条垂直或水平摆放的线将所有 N 个奶牛所在位置全部覆盖。
输入格式
第一行包含整数 N。
接下来 N 行,每行包含两个整数 xi,yi,表示一头奶牛所在位置的横纵坐标。
输出格式
如果可以通过三条垂直或水平摆放的线将所有 N 个奶牛所在位置全部覆盖,请输出 1,否则输出 0。
数据范围
1≤N≤50000, 0≤xi,yi≤109
输入样例:
6
1 7
0 0
1 2
2 0
1 4
3 4
输出样例:
1
样例解释
y=0,x=1,y=4可满足将所有奶牛位置覆盖。
思路
首先考虑到坐标范围很大,需要离散化,但是这里我没有离散,直接用map结构处理了。 我们需要寻找四个值:
1.所有不同x(水平方向)取值的种类数xx1
2.所有不同y(垂直方向)取值的种类数yy1
3.选择一个x坐标进行水平监控,可以减少的最多的需要监控的不同y坐标种类数xx2
4.选择一个y坐标进行垂直监控,可以减少的最多的需要监控的不同x坐标种类数yy2
代码
#include<iostream>\
#include<algorithm>\
#include<string.h>\
#include<stdio.h>\
#include<map>\
using namespace std;\
map<int,int> x1,x2,y1,y2;\
struct node{\
int x,y;\
}Data[50005];\
int xx1,xx2,yy1,yy2;\
int n;\
int main(){\
scanf("%d",&n);\
for(int i=1;i<=n;++i){\
int x,y;\
scanf("%d%d",&x,&y);\
Data[i].x=x;Data[i].y=y;\
if(x1.find(Data[i].x)==x1.end()){\
x1[x]=1;\
xx1++;\
}else\
x1[x]++;\
if(y1.find(y)==y1.end()){\
y1[y]=1;\
yy1++;\
}else\
y1[y]++;\
}\
if(xx1<=3||yy1<=3){\
printf("1\n");\
return 0;\
}\
for(int i=1;i<=n;++i){\
int x=Data[i].x,y=Data[i].y;\
if(y1[y]<=1){\
x2[x]++;\
xx2=max(xx2,x2[x]);\
}\
if(x1[x]<=1){\
y2[y]++;\
yy2=max(yy2,y2[y]);\
}\
}\
if(xx2+2>=yy1||yy2+2>=xx1){\
printf("1\n");\
}else\
printf("0\n");\
return 0;\
}