算法题(三条线)

187 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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;\
}