2 条题解
-
0
/* 位运算+贪心
- 一开始设两个变量,一个二进制全部是1,一个全部是0,然后让他们经过所有的运算,接着每一位贪心,如果某一位原来是0,之后是1的话必须标1这一位.
- 原来是1之后是1的话就判断一下是否符合条件 (是否会比m大),符合就把这一位标1, 不符标0; 原来是0或1,之后是0的话就直接标0.
- 为什么可以这么贪? 因为在位运算里每一位都是独立的不受其他位影响。如果一个位是1经过一些位运算之后是1,那么不管其他位是什么,只要那个位是1,经过相同运算就还是1 */
#include <bits/stdc++.h> using namespace std; int main() { char st[10];int n, m;scanf("%d%d", &n, &m ); int h0=0; //全设0 int h1=(1<<30)-1+(1<<30); //全设1, (10^9=111011100110101100101000000000,有30位) (注:此处可能为笔误,实际应为(1<<30)-1表示30个1,或其他逻辑) for(int i=1,x; i<=n; i++) { scanf("%s%d", st, &x ); if(st[0]=='A' ) h1 &= x, h0 &= x; else if( st[0]=='O' ) h1 |= x, h0 |= x; else h1 ^= x, h0 ^= x; } int ans=0, x=0; for(int i=30;i>=1;i--) { if( h0 & (1<<(i-1)) ) ans += (1<<(i-1)); //如果原来是0之后是1, 就选这个, 让数字尽量小 else { if ( ( h1 & (1<<(i-1)) ) && ( x + (1 << (i-1)) ) <= m ) ans += (1<<(i-1)), x += (1 << (i-1)); //原来是1之后还是1, 判断是否会比m大 } } printf("%d\n", ans); return 0; } -
0
/* 位运算+贪心 * 一开始设两个变量,一个二进制全部是1, 一个全部是0, 然后让他们经过所有的运算, * 接着每一位贪心, 如果某一位原来是0, 之后是1的话必须标1这一位. * 原来是1之后是1的话就判断一下是否符合条件 (是否会比m大), * 符合就把这意味标1,不符标0; 原来是0或1, 之后是0的话就直接标0. * 为什么可以这么贪? 因为在位运算里每一位都是独立的不受其他位影响。 * 如果一个位是1经过一些位运算之后是1, 那么不管其他位是什么, 只要那个位是1, * 经过相同运算就还是1 */ #include<bits/stdc++.h> using namespace std; int main() { char st[10];int n,m;scanf("%d%d", &n, &m ); int h0=0; //全设0 int h1=(1<<30)-1+(1<<30); //全设1, (10^9=111011100110101100101000000000,有30位) for(int i=1,x; i<=n; i++) { scanf("%s%d", st, &x ); if(st[0]=='A' ) h1 &= x, h0 &= x; else if( st[0]=='O' ) h1 |= x, h0 |= x; else h1 ^= x, h0 ^= x; } int ans=0,x=0; for(int i=30;i>=1;i--) { if( h0 & (1<<(i-1)) ) ans+= (1<<(i-1)); //如果原来是0之后是1, 就选这个, 让数字尽量小 else { if ( ( h1 & (1<<(i-1)) ) && ( x+(1 << (i-1)) ) <= m ) ans+= (1<<(i-1)),x+=(1 << (i-1));//原来是1之后还是1, 判断 } } printf("%d\n",ans); return 0; }
- 1
信息
- ID
- 5333
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 2
- 上传者