A. And Matching

链接:https://codeforces.com/problemset/problem/1630/A
题目:

思路:
1.首先k=0时很显然所有的pair为:{i,n-i}
2.k<n-1时所有的pair为{0,n-k-1},{k,n-1},{i,n-i}可以结合位运算的性质来看
3.k=n-1的时候,当n=4或2时显然没有。
当n>4时可以如下分析:首先需要合成的是11111(举例)
考虑如下组合:{00000,11111},{10000,11110},{01000,11101},{00100,10111},{00010,11011},{00001,01111}就是互补,然后剩下的按照k=0的排法排,这样就不会影响11111的合成。
怎么考虑位数?就用这一段:

for (int i = 1; i < n - 1; i++)
{
	int nums = 0;
	int x = 1;
	while (x < n)
	{
		nums += (x & i)?1:0;
		x <<= 1;
	}
	id[nums].push_back(i);
}

然后需要注意的是中间的数要移位,否则会出现{00100,11011}的情况。
代码

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
#define IOS ios::sync_with_stdio(false), cin.tie(0) ,cout.tie(0)
using namespace std;
typedef long long ll;
const int N = 20;
vector<int>id[N];
int main()
{
	IOS;
	int t; cin >> t;
	while (t--)
	{
		vector<int>a;
		for (int i = 0; i < N; i++)id[i] = a;
		ll n, k; cin >> n >> k;
		if (k == n - 1) 
		{
			if(n == 2 or n == 4)
				cout << -1 <<'\n';
			else
			{
				cout << 0 << ' ' << n - 1<< '\n';
				for (int i = 1; i < n - 1; i++)
				{
					int nums = 0;
					int x = 1;
					while (x < n)
					{
						nums += (x & i)?1:0;
						x <<= 1;
					}
					id[nums].push_back(i);
				}
				int size = log2(n);
				if (id[1].size() % 2)swap(id[1][id[1].size() / 2], id[1][id[1].size() / 2 + 1]);
				for (int u = 0; u < id[1].size(); u++)
					cout << id[1][u] << ' ' << id[size - 1][u] << '\n';
				for (int i = 2; i < size - i; i++)
					for (int u : id[i])
						cout << u << ' ' << n - 1 - u << '\n';
				if (size % 2 == 0)
				{
					for (int u : id[size / 2])
						if (u > n - 1 - u)break;
						else cout << u << ' ' << n - 1 - u << '\n';
				}
			}
		}
		else if (k == 0) { for (int i = 0; n - i > i; i++)cout << i << ' ' << n - i - 1  << '\n'; }
		else
		{
			ll a = n - k - 1;
			cout << 0 << ' ' << a << '\n' << n - 1 << ' ' << k << '\n';
			for (int i = 1; n - i > i; i++)
			{
				if (i != k and i != n - k - 1)
					cout << i << ' ' << n - i - 1<< '\n';
			}
		}
	}

	return 0;
}

posted on 2024-07-01 22:39  WHUStar  阅读(4)  评论(0编辑  收藏  举报