每天一道 CodeForces 构造/思维题 (day4)

简介: 每天一道 CodeForces 构造/思维题 (day4)

题目 And Matching

题目链接 And Matching

题目大意:

在这里插入图片描述

给你一个集合包含0,1,2,, n-1共n(2的整数次幂)个整数,在给你一个数字k(0<=k<=n-1),问能否将这个集合分成n/2组,每组两个整数a和b,并且每组按位与的和等于k?

思路:位运算+构造

这题我刚看到的时候没有上面特别清晰的思路,然后就去推样例,这里给了四个样例

  • 4 00 3,1 2
  • 4 1: 1 3 ,0 2
  • 4 2: 2 3 ,0 1

从这几个样例中我们可以找到一个规律

  • k == 0 :我们可以让每一个x(0<=x<n/2)n-1-x(x的补码)配对,这样总和一定是0
  • 0 < k < n-1 :只需要kn-1配对,0与k的补码配对,剩下的还是原来k==0时的配对
  • k == n - 1:n == 4 时,没有解决方案,n >= 8 时,有很多解决方案:

    -    `n-1`与`n-2`配对,结果是`n-1`
    -   `1`与`n-3`配对,结果是`1`
    -   `0`与`2`配对,结果是`0`
    -   剩下的和k==0时的配对一样

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef priority_queue<int, vector<int>, less<int>> Q;
#define x first
#define y second
const int N = 1e5 + 10;
int match[N];
bool st[N];
void solve()
{
    int n, k;
    int cnt = 0;
    memset(st, 0, sizeof st);
    memset(match, -1, sizeof match);
    cin >> n >> k;
    if (k == n - 1 && n == 4)
    {
        puts("-1");
        return;
    }
    if (k == 0)
    {
        for (int i = 0; i < n / 2; i++)
        {
            cout << i << " " << n - i - 1 << '\n';
        }
        return;
    }
    else if (k < n - 1)
    {
        match[0] = n - k - 1;
        match[n - k - 1] = 0;
        match[k] = n - 1;
        match[n - 1] = k;
    }
    else
    {
        match[n - 1] = n - 2;
        match[n - 2] = n - 1;
        match[n - 3] = 1;
        match[1] = n - 3;
        match[0] = 2;
        match[2] = 0;
    }

    for (int i = 0; i < n / 2; i++)
    {
        if (match[i] != -1)
            continue;
        match[i] = n - i - 1;
        match[n - i - 1] = i;
    }
    for (int i = 0; i < n; i++)
    {
        if (st[i])
            continue;
        st[i] = st[match[i]] = true;
        cout << i << " " << match[i] << '\n';
    }
    return;
}
signed main()
{
    // freopen("in.in", "r", stdin);
    // freopen("out.out", "w", stdout);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}
相关文章
|
2月前
|
机器学习/深度学习 人工智能 算法
Transformer打破三十年数学猜想!Meta研究者用AI给出反例,算法杀手攻克数学难题
《PatternBoost: Constructions in Mathematics with a Little Help from AI》提出了一种结合传统搜索算法和Transformer神经网络的PatternBoost算法,通过局部搜索和全局优化交替进行,成功应用于组合数学问题。该算法在图论中的Ramsey数研究中找到了更小的反例,推翻了一个30年的猜想,展示了AI在数学研究中的巨大潜力,但也面临可解释性和通用性的挑战。论文地址:https://arxiv.org/abs/2411.00566
97 13
|
10月前
|
人工智能 自然语言处理 算法
思维链不存在了?纽约大学最新研究:推理步骤可省略
【5月更文挑战第26天】纽约大学研究发现,Transformer模型在处理复杂任务时可能不依赖思维链,而是通过填充符号实现计算。实验显示,填充符号能提升模型在特定任务中的准确率,扩展其表达能力,尤其是在处理嵌套量词问题时。然而,模型有效利用填充符号的学习是个挑战,因填充符号的隐藏层表示不易判断。研究提示,Transformer模型可能通过填充符号并行化解决TC0类问题,但可能使决策过程变得不透明,影响可解释性。该研究为优化语言模型提供了新思路,但也提出了可解释性与计算效率之间平衡的议题。[链接](https://arxiv.org/pdf/2404.15758)
94 1
|
10月前
|
JavaScript
判断关系属于哪一种范式(期末考试必看)
判断关系属于哪一种范式(期末考试必看)
67 1
|
监控 架构师 程序员
第八章 思维模型
第八章 思维模型
158 0
|
机器学习/深度学习
将现实问题转换为编程问题
考虑到一共五个人,直接模拟推理有些太难,计算机最擅长的遍历此时就会派上用场,将每个人从第1到第5来一遍,则一共会产生5^5种可能性,这个只需要一个5层循环即可搞定。但是这样会导致一些不期望出现的结果出现,因为并没有查重,所以会出现两个人抢名次的情况,也就是两个人或者更多的人名次相同的情况,例如两个第二,三个第三这样的,所以即使满足了条件,也要查看一下五个人的名次是否重复,这个交给一个函数来执行,只要五个人名次并列,那就返回0,否则返回1即可。有了这个思路,就能完成以下代码。
128 0
|
人工智能 算法 安全
8种提升程序猿编程能力的方法+编程思维四个核心:分解、抽象、模式识别和算法
对于程序员来说,提高自己的编程能力,算是给自己定的职业发展目标之一,不过定一个成为编程大神的目标很容易,具体做起来可能就不是一件简单的事了。首先,既然决定“我要变得更好”,得先知道“更好”是什么样子的。另外,不能“想变得更好”,却没有任何具体可行的措施。
1006 2
8种提升程序猿编程能力的方法+编程思维四个核心:分解、抽象、模式识别和算法
|
人工智能
每天两道 CodeForces 构造/思维题 (day5)
每天两道 CodeForces 构造/思维题 (day5)
每天两道 CodeForces 构造/思维题 (day5)
codeforces1013——D. Chemical table(思维+转化+并查集)
codeforces1013——D. Chemical table(思维+转化+并查集)
97 0
codeforces 1393 —— B. Applejack and Storages (思维)
codeforces 1393 —— B. Applejack and Storages (思维)
101 0