将十进制数 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] = ' ';
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++ 中异或使用^符号。
#includeusing 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; }



