位运算妙用(二进制)

巧妙的运用进制, 可以解决很多问题!

怎么快速的转换进制:

//了解
#include<bits/stdc++.h>
using namespace std;
int main() {
    char s2[100];
    itoa(101, s2, 2);
    cout << s2 << endl;
    return 0;
}

itoa (要转换的数,转换放在那个数组(char), 转换成几进制);

二进制的运用:

1.二进制 + DP = 状态压缩DP;

eg: 91. 最短Hamilton路径 - AcWing题库

 

/*//
Problem:91.最短Hamilton路径
Contest: 基础算法
URL:  https://www.acwing.com/problem/content/1000/
/*/
#include <bits/stdc++.h>
#define ll long long int
#define ull unsigned long long int
using namespace std;
const int inf = 0x3f3f3f3f;
const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const int N = 20;
const int M = 1 << N;
int n;
int mp[N][N];
int f[M][N];

void init() {
	memset(f, inf, sizeof f);
	f[1][0] = 0;
}

int solve() {
	init();
	for (int i = 0; i < 1 << n; i ++) {
		for (int j = 0; j < n; j ++) {
			if (i >> j & 1) {
				for (int k = 0; k < n; k ++) {
					if (((i - (1 << j)) >> k) & 1) {
						f[i][j] = min(f[i - (1 << j)][k] + mp[k][j], f[i][j]);
					}
				}
			}
		}
	}
	return f[(1 << n) - 1][n - 1];
}

int main(int argc, char const *argv[]) {
	ios::sync_with_stdio(false);
	cin.tie(0);     cout.tie(0);
	cin >> n;
	for (int i = 0; i < n; i ++) {
		for (int j = 0; j < n; j ++) {
			cin >> mp[i][j];
		}
	}
	cout << solve() << endl;
	return 0;
}

2.二进制 + 乘法 = (一定程度上)大数乘法

eg:90. 64位整数乘法 - AcWing题库

/*//
Problem:90. 64位整数乘法
Contest:  基本算法
URL: https://www.acwing.com/problem/content/description/92/
/*/
#include <bits/stdc++.h>
#define ll long long int
#define ull unsigned long long int
using namespace std;
const int inf = 0x3f3f3f3f;
const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;

void solve(ll a, ll b, ll p) {
	ll res = 0;
	while (b) {
		if (b & 1) {
			res = (res + a) % p;
		}
		a = (2 * a) % p;
		b /= 2;
	}
	cout << res << endl;
}

int main(int argc, char const *argv[]) {
	ios::sync_with_stdio(false);
	cin.tie(0);     cout.tie(0);
	ll a, b, p;
	cin >> a >> b >> p;
	solve(a, b, p);
	return 0;
}

 3.二进制 + 搜索 = 经典多钥匙开门搜索问题(每一位对应一个数、一把钥匙)/ 或者情况选择问题:

eg:998. 起床困难综合症 - AcWing题库

/*//
Problem: 998. 起床困难综合症
Contest: 基础算法
URL: https://www.acwing.com/problem/content/1000/
/*/
#include <bits/stdc++.h>
#define ll long long int
#define ull unsigned long long int
using namespace std;
const int inf = 0x3f3f3f3f;
const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
int n, m;
struct door {
	string op;
	int w;
} dor[2 * maxn];

int OP(int a, int b) {
	int res = a;
	for (int i = 1; i <= n; i ++) {
		if (dor[i].op[0] == 'A') {
			res &= dor[i].w >> b & 1;
		}
		if (dor[i].op[0] == 'O') {
			res |= dor[i].w >> b & 1;
		}
		if (dor[i].op[0] == 'X') {
			res ^= dor[i].w >> b & 1;
		}
	}
	return res;
}

int  solve() {
	int ans = 0;
	for (int i = 32; i >= 0; i --) {
		if (m >> i) {
			int one = OP(1, i);
			int zero =  OP(0, i);
			if (zero >= one) {
				ans |= zero << i;
			} else {
				ans |= one << i;
			}
		} else {
			ans |= OP(0, i) << i;
		}
	}
	return ans;
}
int main(int argc, char const *argv[]) {
	ios::sync_with_stdio(false);
	cin.tie(0);     cout.tie(0);

	cin >> n >> m;
	for (int i = 1; i <= n;  i ++) {
		cin >> dor[i].op >> dor[i].w;
	}
	cout <<  solve() << endl;
	return 0;
}

92. 递归实现指数型枚举 - AcWing题库

/*//
Problem: 92. 递归实现指数型枚举
Contest: 递归与递推
URL: https://www.acwing.com/problem/content/94/
/*/
#include <bits/stdc++.h>
#define ll long long int
#define ull unsigned long long int
using namespace std;
const int inf = 0x3f3f3f3f;
const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;

// 注意这里面选 0 个时要输出空格
int n;
void solve(int x, int state) {
	if (x == n) {
		for (int i = 0; i < n; i ++) {
			if (state >> i & 1) {
				cout << i + 1 << " ";
			}
		}
		cout << endl;
		return;
	}
	solve(x + 1, state | (1<<x));
	solve(x + 1, state);
}

int main(int argc, char const *argv[]) {
	ios::sync_with_stdio(false);
	cin.tie(0);     cout.tie(0);
	cin >> n;
	solve(0, 0);
	return 0;
}

93. 递归实现组合型枚举 - AcWing题库

/*//
Problem: 93. 递归实现组合型枚举
Contest: 递归与递推
URL: https://www.acwing.com/problem/content/95/
/*/
#include <bits/stdc++.h>
#define ll long long int
#define ull unsigned long long int
using namespace std;
const int inf = 0x3f3f3f3f;
const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
int n, m;
struct node {
	int state1;
	int cnt;
};
// bool cmp(node x1, node x2) {
// 	return x1.state1 > x2.state1;
// }
vector<node > ans;
void solve(int x, node state, int flag) {
	if (flag) {
		state.cnt ++;
		state.state1 |= (1 << (x-1));
	} 
	if (x == n) {
		if (state.cnt == m) {
			ans.push_back(state);
		}
		return ;
	}
	solve(x + 1, state, 1);
	solve(x + 1, state, 0);
}

int main(int argc, char const *argv[]) {
	ios::sync_with_stdio(false);
	cin.tie(0);     cout.tie(0);

	cin >> n >> m;
	node state;
	state.cnt = 0;
	state.state1 = 0;
	solve(0, state, 0);
	// sort(ans.begin(), ans.end(), cmp);
	reverse(ans.begin(), ans.end());
	for(int i = 0; i < ans.size(); i ++) {
		for(int j = 0; j < n; j ++) {
			if(ans[i].state1 >> j & 1) {
				cout << j + 1 << " ";
			}
		}
		cout << endl;
	}
	return 0;
}

总而言之二进制非常好用!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将十进制转换成二进制可以使用位运算与运算来实现。 具体步骤如下: 1. 将十进制数不断右移,直到为0,得到每一二进制数。 2. 将每一二进制数从右往左依次存储到一个数组中。 3. 对于两个二进制数相加,可以模拟竖式相加的过程。从右往左依次相加,如果相加的结果大于等于2,需要进。 4. 对于进的情况,可以使用与运算和异或运算来实现。与运算可以得到需要进异或运算可以得到不需要进。 下面是一个示例代码: ```c #include <stdio.h> // 将十进制转换成二进制 void decimalToBinary(int decimal, int binary[]) { int i = 0; while (decimal > 0) { binary[i] = decimal % 2; decimal /= 2; i++; } } // 将两个二进制数相加 void binaryAdd(int binary1[], int binary2[], int result[]) { int carry = 0; for (int i = 0; i < 32; i++) { int sum = binary1[i] + binary2[i] + carry; if (sum >= 2) { result[i] = sum - 2; carry = 1; } else { result[i] = sum; carry = 0; } } } // 输出二进制数 void printBinary(int binary[]) { int i; for (i = 31; i >= 0 && binary[i] == 0; i--); for (; i >= 0; i--) { printf("%d", binary[i]); } printf("\n"); } int main() { int decimal1 = 23; int decimal2 = 11; int binary1[32] = {0}; int binary2[32] = {0}; int result[32] = {0}; decimalToBinary(decimal1, binary1); decimalToBinary(decimal2, binary2); printf("Binary1: "); printBinary(binary1); printf("Binary2: "); printBinary(binary2); binaryAdd(binary1, binary2, result); printf("Result: "); printBinary(result); return 0; } ``` 输出结果如下: ``` Binary1: 10111 Binary2: 1011 Result: 100110 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值