Codeforces Round #768 (Div. 2) C

C. And Matching

题意:给出一个n和k,要求对由0,1,2,… ,n-1组成的数组,分成n/2对,使每一对两个数的相与的和为k,n为2的次幂,要求给出一种划分方案。

QQ截图20220429113135.png

思路

对于a&b = 0,我们可以定义f(a) = b,至于如何构造,我们发现a=101,b=010,a^b = 111,那么可以由a^(n-1)得到b,因为n是2的次幂,所以n-1就是范围内最长的,

由此我们可以构造出k=0的情况,即0&(n-1),1&(n-2),2&(n-3)…,

交换其中的一些数对,可以得到别的k值,例如对于0<k<n-1的所有情况都可以用k&(n-1),0&(f(k)),其他仍为0,比较特殊的有k=n-1的情况,因为n-1是最大的数了,不能直接&得到,所以可由1+n-2的情况得到,而对于n=4,k=3则无法得到。

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int mod=1000000007 , N = 7e4;
const double eps=1e-8;
bool st[N];
int n,k;
int f(int a)
{
	return a^(n-1);
}
int main(){
	int t;
	cin>>t;
	while(t--)
	{
		memset(st,0,sizeof st);
		cin>>n>>k;
		if(k == 0)
		{
			for(int i = 0 ; i < n ; i ++ )
				if(!st[i])
				{
					cout<<i<<" "<<f(i)<<'\n';
					st[i] = st[f(i)] = 1;
				}
		}
		else if(k == n-1 && n == 4)	cout<<"-1\n";
		else if(k == n-1 && n != 4)
		{
			cout<<n-2<<" "<<n-1<<"\n";
			cout<<0<<" "<<2<<"\n";
			cout<<1<<" "<<n-3<<"\n";
			st[0] = st[1] = st[2] = st[n-1] = st[n-2] = st[n-3] = 1;
			for(int i = 2 ; i < n ; i ++ )
				if(!st[i])
				{
					cout<<i<<" "<<f(i)<<'\n';
					st[i] = st[f(i)] = 1;
				}
		}
		else
		{
			cout<<k<<" "<<n-1<<"\n";
			cout<<0<<" "<<f(k)<<"\n";
			st[0] = st[k] = st[n-1] = st[f(k)] = 1;
			for(int i = 2 ; i < n ; i ++ )
				if(!st[i])
				{
					cout<<i<<" "<<f(i)<<'\n';
					st[i] = st[f(i)] = 1;
				}
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值