http://codeforces.com/contest/851/problem/C
- 题意
- 给出 n 个五维空间的点
- 一个点a为 bad 的定义为 存在两点 b, c, 使的<ab, ac> 为锐角
- 分析
- 在二维平面内, 选取坐标轴原点为a点, 其余点数大于4时, 由鸽巢定理必定有至少两个点位于同一象限
- 此时位于统一象限的点与原点夹角为锐角
- 在三维空间内, 选取坐标轴原点为a点, 其余点数大于8时, 同理必有至少两个点位于同一卦限
- 位于同一卦限的两个点与原点构成锐角
- 推广, 5维空间内, 除原点外有大于(1<<5) = 32 个时, 必定存在锐角.
所以当点数大于 32+1 的时候, 必定没有好点.
当 n <= 33 时, n^3暴力即可
#include <stdio.h>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int MAX = 1111;
int bad[MAX], mtx[MAX][5], n, i, j, k, m, t, l, cnt;
long long sum;
int ij[5], jk[5], ik[5];
bool ck;
int main() {
// freopen("in.t", "r", stdin);
// freopen("out.t", "w", stdout);
while(scanf("%d", &n) == 1) {
for ( i = 0; i < n; ++i)
for ( j = 0; j < 5; ++j)
scanf("%d", &mtx[i][j]);
if (n > ((int)1<<5)+1) {
puts("0");
continue;
}
cnt = n;
memset(bad, 0, sizeof(bad));
for (i = 0; i < n; ++i) {
for (j = 0; !bad[i] && j < n; ++j) {
if (j == i) continue;
for (k = 0; !bad[i] && k < n; ++k) {
if (k == i) continue;
if (k == j) continue;
sum = 0;
for (t = 0; t < 5; ++t)
sum += ((long long)mtx[j][t]-mtx[i][t])
*(mtx[k][t]-mtx[i][t]);
if (sum > 0)
bad[i] = 1, --cnt;
}
}
}
printf("%d\n", cnt);
for (i = 0; i < n; ++i) {
if (!bad[i])
printf("%d\n", i+1);
}
}
return 0;
}