NP问题
问题描述:
p6pou在平面上画了n个点,并提出了一个问题,称为N-Points问题,简称NP问题。
p6pou首先在建立的平面直角坐标系,并标出了这n个点的坐标。
这n个点的坐标都是正整数,任意三个点都不共线。
然后,p6pou选择其中一个点A,画一条y轴的平行线,这条直线称为l。
直线l以A点为旋转中心逆时针旋转,当直线l碰到另外一个点B时,就立刻将B点作为新的旋转中心继续逆时针旋转。
此后,每当直线l碰到除了旋转中心以外的另一个点,都会将这个点作为新的旋转中心继续逆时针旋转。这个过程可以一直进行。
p6pou不太关心旋转的完整过程,只想知道,当l旋转至平行于x轴时直线方程有哪些可能。
3≤n≤200,1≤xi,yi,A≤10^6,A∈{x1,x2,…,xn} 。
分析:
多画几个图可以发现,一条直线能将一个平面分成两半,两端的点数个数之差一定!
#include<bits/stdc++.h> using namespace std; #define re register int #define LL long long struct node{int x, y;}a[500]; bool cmp(node x,node y){return x.y < y.y;} int ans[500], ls, rs, mi; int main() { int n, A; scanf("%d%d",&n,&A); for(re i=1;i<=n;++i) { int x, y; scanf("%d%d",&x,&y); if(x<A)ls++; if(x>A)rs++; if(x==A)mi++; a[i]=(node){x, y}; } sort(a+1, a+1+n, cmp); for(re i=1, s=0;i<=n;++i, ++s) { int t1=s, t2=n-s-1; if(abs(abs(ls-rs)-abs(t1-t2))<=(mi==2))ans[++ans[0]]=a[i].y; } ans[0]=unique(ans+1, ans+1+ans[0])-ans-1; for(re i=1;i<=ans[0];++i)printf("%d\n", ans[i]); return 0; }