E. Divide Points(思维、数论)

题目链接:https://codeforces.com/contest/1270/problem/E
题意:给定n个点,现在需要将这n个点划分为2个集合,将集合内任意两点的欧几里得距离标记为红,将集合间的点对的欧几里得距离标记为绿,现要求红色和绿色距离不能有相同的,求划分方案,有多个划分方案,输出任意一种。保证至少有一种划分方案。

官方题解:奇数偶划分,划分为00、01、10、11;如果还分不出时,继续除2划分。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1010;
 
int n;
int x[maxn],y[maxn];
 
vector<int> v[5];//00 01 10 11
vector<int> v2[5];// 0 1
int Judge(int x,int y){
	return (((x%2)<<1)+(y%2));
}
int Judge2(int x,int y){
	return (x+y)%2;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x[i],&y[i]);
		x[i]+=1000000;
		y[i]+=1000000;
	}
	while(1){
		for(int i=0;i<4;i++) v[i].clear();
		v2[0].clear();v2[1].clear(); 
		for(int i=1;i<=n;i++){
			v[Judge(x[i],y[i])].push_back(i);
			v2[Judge2(x[i],y[i])].push_back(i);
		} 
		if(!v2[0].empty()&&!v2[1].empty()){
			int m=(int)v2[0].size();
			printf("%d\n",m);
			for(int j=0;j<m;j++) printf("%d ",v2[0][j]);
			break;//
		}else if(!v[0].empty()&&!v[3].empty()){
			int m=(int)v[0].size();
			printf("%d\n",m);
			for(int j=0;j<m;j++) printf("%d ",v[0][j]);
			break;//
		}else if(!v[1].empty()&&!v[2].empty()){
			int m=(int)v[1].size();
			printf("%d\n",m);
			for(int j=0;j<m;j++) printf("%d ",v[1][j]);
			break;//
		}else{
			for(int i=1;i<=n;i++) x[i]>>=1,y[i]>>=1;
		}
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值