题意

\(n\)个二维平面上的点,每两个点之间连一条线段,将这些点划分为两个非空的集合\(A\)\(B\),同一个集合内的两点之间线段用黄色标注,不同集合的两点之间线段用蓝色标注,使距离相同的线段颜色相同。

分析

先将所有点的坐标以其中一个点作为原点转化一下,使其中必定有一个点是\((0,0)\)
然后将所有点按奇偶分为四组(0代表偶数,1代表奇数):\(A_{00},A_{10},A_{01},A_{11}\)
如果所有点同在\(A_{00}\)中,将所有点的坐标除2,直到至少有一个点的一个坐标是奇数。

  • \(A_{01}\)\(A_{10}\)是非空的,将\(A_{00}\)\(A_{11}\)中的所有点分到一个集合,\(A_{01}\)\(A_{10}\)中的所有点分到另一个集合,来自相同集合的两点之间距离为偶数,来自不同集合的两点之间距离为奇数,符合要求。
  • \(A_{01}\)\(A_{10}\)都是空的,那么\(A_{11}\)一定不是空的,将\(A_{00}\)中的所有点分到一个集合,\(A_{11}\)中的所有点分到另一个集合,来自相同集合的点之间的距离为\(8k^2\)可被4整除,来自不同集合的两点之间距离为\(8k^2+8k+2\)除4余2,符合要求。

Code

#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
#define pb push_back
#define ll long long
using namespace std;
const int inf=1e9;
const int mod=1e9+7;
const int maxn=1e5+10;
int n;
int x[1010],y[1010];
vector<int>a[2][2];
int main(){
	ios::sync_with_stdio(false);
	//freopen("in","r",stdin);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>x[i]>>y[i];
	}
	int flag=1;
	for(int i=n;i>=1;i--){
		x[i]-=x[1],y[i]-=y[1];
		if(x[i]&1) flag=0;
		if(y[i]&1) flag=0;
	}
	while(flag){
		for(int i=1;i<=n;i++){
			x[i]/=2;y[i]/=2;
			if(x[i]&1) flag=0;
			if(y[i]&1) flag=0;
		}
	}
	for(int i=1;i<=n;i++){
		a[x[i]&1][y[i]&1].pb(i);
	}
	if(!a[0][1].empty()||!a[1][0].empty()){
		cout<<(int)(a[0][0].size()+a[1][1].size())<<endl;
		for(int x:a[0][0]) cout<<x<<" ";
		for(int x:a[1][1]) cout<<x<<" ";
	}else{
		cout<<(int)a[0][0].size()<<endl;
		for(int x:a[0][0]) cout<<x<<" ";
	}
	return 0;
}