CF1097B 题解
开锁问题 题解
题目大意
有一个锁,初始指针指向 YES,否则输出 NO。
题目解析
大部分题解都使用的是 DFS 二决策枚举,还有使用 位运算 + 递推 的,本文就不再赘述。本文介绍一种二进制枚举的方法。
我们每次转动都有
例如
位运算简单学习(已学过可跳过)
位运算是一种二进制专用的运算,没有进位和借位,每一位之间相互独立。
按位与 &:对两个数字每一位计算,两位都为 1,答案为 1,至少一位为 0,答案为 0。
按位或 |:对两个数字每一位计算,两位都为 0,答案为 0,至少一位为 1,答案为 1。
按位异或 |:对两个数字每一位计算,两位不同,答案为 1,两位相同,答案为 0。
按位非 ~:对一个数字每一位计算,这一位为 0,答案为 1,这一位为 1,答案为 0。
左移 <<:对一个数字每一位计算,最左边舍弃,最右边补 0。
右移 >>:对一个数字每一位计算,最右边舍弃,最左边补 0。
注:位运算的运算优先级很低,当你不知道它的运算优先级时,你可以多加一些括号来增高运算优先级。
代码
#include <iostream>
using namespace std;
int main()
{
int n; // 输入
cin >> n;
int a[16];
for (int i = 0; i < n; ++i)
{
cin >> a[i];
}
for (int i = 0; i < (1 << n); ++i)
// 枚举,i 的二进制表示转动方案(从 1 到 2 的 n 次方),j 表示转动到了第几位
{
int sum = 0;
for (int j = 0; j < n; ++j)
{
if ((i >> j & 1) == 1) // i 的二进制的从右往左数第 j 位为 1
{
sum += a[j];
}
else
{
sum -= a[j];
}
}
if (sum % 360 == 0) // 输出答案
{
cout << "YES";
return 0;
}
}
cout << "NO";
return 0;
}