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;
}