Logo FiraCode 的博客

博客

CF1630A题解

...
FiraCode
2025-12-01 12:55:18
什么意思呢

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2022-04-14 21:17:26

题解思路:

有一个很显然的性质:

$x\ n - x$ 的二进制每一位都是相反的。

所以我们可一构造出 $k=0$ 时的情况。

当$k \ne n-1$ 的时候:

我们就可以让 $k$ 和 $n - 1$ 组成一组。

再让 $n - k + 1$ 和 $0$ 构成一组

接下来就是 $k = n-1$ 的情况:

若 $k=n-1$,那我们就不能 $n - 1$ 和 $n - 1$,$0$ 和 $0$ 分成一组。

因为要 $n\ge 4$,即二进制至少有两位。

$(0){10} = (0){2}$, $(1){10} = (1){2}$, $(2){10} = (10){2}$, $(3){10} = (11){2}$。

$(n - 4){10} = ((??????...-1)11){2}$、

$(n - 3){10} = (?????...00){2}$、

$(n - 2){10} = (?????...01){2}$、

$(n - 1){10} = (?????...10){2}$、

$(n){10} = (??????... 11){2}$。

那么我们可以 $n - 2$ 和 $3$。

$n - 4$ 和 $1$。

$n - 1$ 和 $n - 3$。

$2$ 和 $0$。

特殊情况 $n = 4 , k = 3$ 时构造不出来,输出 $-1$,其他情况都有解,把这种情况特判掉就可以了。

AC CODE:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1 << 20;
int a[N];
int main() {
    int T;
    scanf ("%d" , &T);
    while (T --) {
        int n , k;
        scanf ("%d%d" , &n , &k);
        if (n == 4 && k == 2)puts("-1");\/\/无解情况
        else if (k == 0) {\/\/k=0时
            for (int i = 0; i < n \/ 2; ++ i)
                printf ("%d %d\n" , i , n - 1 - i);
        }else if (k != n -1) {\/\/k!=n-1时
            printf ("%d %d\n" , n - 1 , k);
            printf ("%d %d\n" , n - 1 - k , 0);
            for (int i = 1; i < n \/ 2; ++ i)
                if (i != k && i != n - 1 - k)
                    printf ("%d %d\n" , i , n - 1 - i);
        }else {\/\/k=n-1的情况
            printf ("%d %d\n" , n - 2 , 3);
            printf ("%d %d\n" , n - 4 , 1);
            printf ("%d %d\n" , n - 1 , n - 3);
            printf ("%d %d\n" , 2 , 0);
            for (int i = 4; i < n \/ 2; ++ i)
                printf ("%d %d\n" , i , n - i - 1);
        }
    }
    return 0;
}

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。