链接: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;
}
写的可能有点啰嗦了,但是也是为了尽可能把思路弄清楚明白一些...不足的地方希望大家多多包涵。