进制转换 + 位运算

十进制转二进制:

十进制转 k 进制:

将十进制数 n 转换为 k(k≤35) 进制数。(注:如果某个数字 r≥10 则使用字符 'A' + (r - 10) 代替)

char digit[25];
void change(int n, int k) {
    int m = 0;
    while (n) {
        int r = n % k;
        if (r < 10) {
            digit[m++] = '0' + r;
        } else {
            digit[m++] = 'A' + (r - 10);
        }
        n /= k;
    }
    digit[m] = '\0';
    for (int i = 0, j = m - 1; i < j; i++, j--) {
        swap(digit[i], digit[j]);
    }
}

 

 

二进制转十进制:

 k 进制转十进制:

将 k 进制数 dight(使用字符数组存储),转换为十进制数。

int change(char digit[25], int k) {
    int n = 0;
    int len = strlen(digit);
    for (int i = 0; i < len; i++) {
        if (digit[i] <= '9') {
            n = n * k + (digit[i] - '0');
        } else {
            n = n * k + (digit[i] - 'A');
        }
    }
    return n;
}

 位运算

计算机中所有的数据都是以二进制的形式存储的,即 0,10,1 两种状态,计算机对二进制数据进行的运算被称为位运算。

3&5 的值得 1。 

    0 0 0 0 0 0 1 1
 &  0 0 0 0 0 1 0 1
 ——————————————————
    0 0 0 0 0 0 0 1

3|5 的值得 7 。 

   0 0 0 0 0 0 1 1
|  0 0 0 0 0 1 0 1
——————————————————
   0 0 0 0 0 1 1 1

3^5 的值得 66 。

   0 0 0 0 0 0 1 1
^  0 0 0 0 0 1 0 1
——————————————————
   0 0 0 0 0 1 1 0

异或的性质

快速记忆法:相同为 0,不同为 1。

1^1 = 0
1^0 = 1
0^1 = 1
0^0 = 0

 

可以发现 00 异或任何数后,都等于该数本身,例如 (11)_2(11)2​ ^ (00)_2 = (11)_2 = (3)_{10}(00)2​=(11)2​=(3)10​。

(重要)根据这个性质,我们可以得出结论:a^b^b的结果等于a。因为两个 b 异或后等于 0 了,0 异或 a 等于 a

 

例题:最大异或和

蒜头君有一个长度为 n 的非负整数数列 ai​。

现在给出一个正整数 mm,蒜头君需要找到一个非负整数 k,满足 k<2m,并且使得数列 aa 的所有数的异或和再与 k 异或的结果最大,即a1​⊕a2​⊕⋯⊕an​⊕k 的结果最大。

输出最大的异或和。

注:yx⊕y 表示的是 x 异或 y,在 C++ 中异或使用^符号。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int a[maxn];
int solve(int x, int m) {
    int bit[35] = {0};
    for (int i = 0; x != 0; i++) {
        bit[i] = x % 2;
        x /= 2;
    }
    for (int i = 0; i < m; i++) {
        bit[i] = 1;
    }
    int ans = 0;
    for (int i = 30; i >= 0; i--) {
        ans = ans * 2 + bit[i];
    }
    return ans;
}
int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    int x = 0;
    for (int i = 1; i <= n; i++) {
        x ^= a[i];
    }
    cout << solve(x, m) << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值