链接:https://ac.nowcoder.com/acm/contest/911/A
来源:牛客网
Good 的集合
题目描述
平面上给 n(3≤n≤1000) 个点,保证不存在 3 点共线,保证这些点两两不重合,对于一个点集 S ,如果从 S 中任意选出三个不同的点,构成的三角形重心都不是整点(横坐标,纵坐标都是整数的点,称为整点),那么这个点集是 good 的,输出最大的 good 的点集大小。(注:所有点数小于等于 2 的点集都是 good 的)。
输入描述:
第一行,一个整数 n (3≤n≤1000),表示 n 个点,之后 n 行,每行两个整数 x[i],y[i] (0≤x[i],y[i]≤106).’
输出描述:
输出一个正整数表示答案。
示例1
输入
4
0 0
0 1
1 0
1 1
输出
4
示例2
输入
3
0 0
1 2
2 1
输出
2
备注:
-
样例 1 所有点都可以加入集合。
-
样例 2,如果 3 个点同时加入集合,重心为 (1,1) 不合法,Good Set 中至多只能 2 个点。
因为中心要 / 3所以先直接/ 3 然后对于每种情况的个数枚举dfs搜索
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1010;
int x[maxn], y[maxn];
int num[4][4];
int ans, n;
bool check(int s){//check符不符合条件
for (int i = 0; i<=s; i++)
for (int j = i+1; j<=s;j++)
for (int k = j+1; k<=s; k++){
int v = x[i] + x[j] + x[k];
int u = y[i] + y[j] + y[k];
if (v % 3 == 0 && u % 3 == 0) return 0;
}
return 1;
}
void dfs(int s){
ans = max(ans, s);
if (s > n) return;
for (int i = 0; i < 3;i++)
for (int j = 0; j < 3; j++){
x[s] = i, y[s] = j;
if (num[i][j]){//枚举当前个数
if (check(s)){
num[i][j]--;
dfs(s + 1);
num[i][j]++;
}
}
}
}
int main(){
cin >> n;
for (int i = 1; i <= n; i++){
int x, y;
cin >> x >> y;
x %= 3;y %= 3;
num[x][y]++;
}
dfs(0);
cout << ans << endl;
return 0;
}