Codeforces Round 742
B. MEXor Mixup
题意
有一个数组,输入两个数a,b,a代表这个数组之外的最小非负整数,b代表这个数组的异或值,问你该数组的最小长度。
思路
首先,a保证了数组至少是由0 ~(a-1) 这些数组成,设0 ~(a-1) 的异或值为x
1.如果x==b,则该数组的最小长度为a
2.如果x!=b,且x^b!=a,此时数组之外的最小非负整数仍为a,又**因为 x^x=0, 0^b=b, a ^ b ^ c = a ^ ( b ^ c ),**所以在原数组加上一个 **x ^ b,x ^ x ^ b = b,**此时该数组最小长度为a+1
3.如果x!=b,且x ^ b==a,就不能直接加x ^ b,因为a的值会改变,所以我们应该改变x^b的形式,让它变成(x ^ b ^ 1 ) ^ 1,所以在原数组加上一个**(x ^ b ^ 1)**和一个1就可以解决了,此时该数组最小长度为a+2
此题还有一个难点就是求x(0到a-1的异或值),打个表发现是有规律的
a%4==1时 x=a-1
a%4==2时 x=1
a%4==3时 x=a
a%4==0时 x=0
**注意坑点!!!**判断的时候有异或操作( ^ ) 的时候加括号,( ^ )的优先级很低,比==还低
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int ans=0;
int a,b;
int c;
scanf("%d%d",&a,&b);
if(a%4==1)
c=a-1;
else if(a%4==2)
c=1;
else if(a%4==3)
c=a;
else
c=0;
if(c!=b&&(c^b)!=a)
ans=a+1;
else if(c==b)
ans=a;
else if(c!=b&&(c^b)==a)
ans=a+2;
printf("%d\n",ans);
}
}
C. Carrying Conundrum
题意
现有一个新的加法定义,输入一个数n,问你有多少对通过新的加法满足 a+b=n的数。
新加法的定义是,每次进位进2位。
思路
在这个定义下,只要把奇数位相加得出一个数x,然后算得到x的a+b的个数,刚好等于x+1,因为(0+x),(1+x-1),(2+x-2)+……+(x+0)。
再把偶数位相加,得出一个数y,然后算得到y的a+b的个数,刚好等于y+1。
然后组合相乘(x+1)*(y+1),又因为a,b为正数,不能出现0的情况,所以还要减2,
最后答案为(x+1)*(y+1)-2.
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
ll x=0,y=0;
ll pw=1;
while(n)
{
x=x+pw*(n%10);
n/=10;
y=y+pw*(n%10);
n/=10;
pw*=10;
}
printf("%d\n",(x+1)*(y+1)-2);
}
}