http://www.elijahqi.win/archives/678
A. Five Dimensional Points
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given set of n points in 5-dimensional space. The points are labeled from 1 to n. No two points coincide.
We will call point a bad if there are different points b and c, not equal to a, from the given set such that angle between vectors and is acute (i.e. strictly less than ). Otherwise, the point is called good.
The angle between vectors and in 5-dimensional space is defined as , where is the scalar product and is length of .
Given the list of points, print the indices of the good points in ascending order.
Input
The first line of input contains a single integer n (1 ≤ n ≤ 103) — the number of points.
The next n lines of input contain five integers ai, bi, ci, di, ei (|ai|, |bi|, |ci|, |di|, |ei| ≤ 103) — the coordinates of the i-th point. All points are distinct.
Output
First, print a single integer k — the number of good points.
Then, print k integers, each on their own line — the indices of the good points in ascending order.
Examples
input
6
0 0 0 0 0
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
output
1
1
input
3
0 0 1 2 0
0 0 9 2 0
0 0 5 9 0
output
0
Note
In the first sample, the first point forms exactly a angle with all other pairs of points, so it is good.
In the second sample, along the cd plane, we can see the points look as follows:
We can see that all angles here are acute, so no points are good.
我们可以知道如果90°的时候应该是最大满足条件,举个例子,二维,在四个坐标系上,正好四个
推广到k维,最多有2*k个。就本题而言,最多10个点能满足题意。也就是说n如果>=12,是一定不满足题意的,直接输出0即可。剩下的情况n很小,可以直接暴力O(n3)判断。
在评论中看到的一个想法,跟大家分享一下:算出两两点之间的连线的长度,找到最小的那条线段,记作ab,则好点一定出自a,b。其他点一定都是坏点。为什么呢?首先,如果另一点c和a,b构成了三角形abc,则小边对小角,角C一定是不大于60°的,也就是说c一定是坏点。另一种情况,a,b,c三点一线,因为ab是最短的,所以c一定在a,b同侧,所以c还是个坏点。综上,除了a,b以外的点都是坏点。我们只需判断a,b是否是好点即可。
#include<cstdio>
#include<cmath>
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int top,q[15],p[15][6];
inline double calc(int x,int y,int z){
int x1[6],x2[6];
for (int i=1;i<=5;++i) x1[i]=p[y][i]-p[x][i];
for (int i=1;i<=5;++i) x2[i]=p[z][i]-p[x][i];
double len1=0,len2=0;
for (int i=1;i<=5;++i) len1+=x1[i]*x1[i];len1=sqrt(len1);
for (int i=1;i<=5;++i) len2+=x2[i]*x2[i];len1=sqrt(len2);
int ans=0;
for (int i=1;i<=5;++i) ans+=x1[i]*x2[i];
return ans/(len1*len2);
}
int n;
int main(){
freopen("cfc.in","r",stdin);
n=read();
if (n>11){printf("0");return 0;}
for (int i=1;i<=n;++i)
for (int j=1;j<=5;++j) p[i][j]=read();
bool flag;
for (int i=1;i<=n;++i){
flag=true;
for (int j=1;j<=n;++j){
if (i==j) continue;
for (int z=1;z<=n;++z){
if (j==z) continue;if (i==z) continue;
if (calc(i,j,z)>0) {
flag=false;break;
}
}
if (flag==false) break;
}
if (flag) q[++top]=i;
}
printf("%d\n",top);
for (int i=1;i<=top;++i) printf("%d\n",q[i]);
return 0;
}