牛客周赛 Round 56 C题异或故事

链接:https://ac.nowcoder.com/acm/contest/88392/C

这题考察的知识点是异或。

关于异或,我们应该掌握以下知识点:

1.两个相同的数异或的结果为0;
2.0和任意一个非零的数异或的结果都是那个非零实数本身;
3.a^b^c=a^(b^c)=(a^b)^c;
4.d=a^b^c-->a=d^b^c;
5.a^b^a=b;
6.a^b=b^a.
7.负数和正数异或的结果为负数,负数和负数异或的结果为正数。

题目给出了一个正整数a,要求我们找出两个数b和c,b和c异或的结果等于a。那我们要怎么找出这两个数呢?

思路一:根据公式我们知道a=b^c可以推出b=a^c。由于a是已知的,所以我们可以令c=1,那么很容易就可以得到b是多少了。如果a是奇数,那么b=a^1=a-1;如果a是偶数,那么b=a^1=a+1,从而我们就可以知道b和c的值是多少了。

思路二:

我们知道0和任意一个非零的数异或的结果都是那个非零实数本身,那么我们是不是可以让b或者c等于0,另一个数等于a就好了。按理说应该是可以的,但是题目要求b和c必须为正整数,所以行不通。但是我们知道a^b^c=a^(b^c)=(a^b)^c,那么我们可以构造一个0出来,也就是0=1^1。所以1^1^a=0^a=a,即b=1,c=(1^a)。

但是由于题目的范围限制,b和c的范围在[1,1e9],所以我们需要特判两个零界点。当a=1时,由于a为奇数,所以当c=1时,b会等于a-1=0,不满足题目要求,所以我们要特判一下。当a=1e9时,由于1e9为偶数,所以当c=1时,b会等于a+1=1e9+1,又越界了,所以这里也要特判。

AC code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int a;

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

    cin >> t;
    while (t--) {
        cin >> a;

        if (a == 1) {
            cout << 2 << " " << 3 << '\n';
            continue;
        }

        if (a == 1000000000) {//因为1和偶数a异或会得到a+1,而a+1越界了,所以此处需要特判
            cout << 999999999 << ' ' << 1023 << '\n';
            continue;
        }

        cout << 1 << " " << (1 ^ a) << '\n';
        // 1 ^ ( 1 ^ a ) = ( 1 ^ 1 ) ^ a = 0 ^ a = a
    }

    return 0;
}

写的可能有点啰嗦了,但是也是为了尽可能把思路弄清楚明白一些...不足的地方希望大家多多包涵。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值