题目:https://codeforc.es/contest/1527
A
题意:给定数字n。求m。使n&(n-1)&(n-2)&...&(m)=0,m是可能的最大值。
题解:转化为二进制可以发现,如果想要每一位都是0,那么必须有一个数最高位是0。设最高位为0,其他位为1的数为x,那么必然存在x到n之间的数使某个位&后为0。
所以题目转化为求x。
#include<iostream> #include<algorithm> #include<vector> #include<map> #include<cmath> #include<cstring> using namespace std; const int mx=50+10; const int inf=1<<30; typedef long long ll; ll two[mx]; void init(){ two[0]=1; for(ll i=1;i<=32;i++){ two[i]=two[i-1]*2; } } void solve(){ init(); ll t; scanf("%lld", &t); for(ll i=1;i<=t;i++){ ll v; scanf("%lld", &v); ll num =0; while(v!=0){ v=v>>=1; num++; } printf("%lld\n", two[num-1]-1); } } int main(){ solve(); return 0; }
B1. Palindrome Game (easy version)
题意:给定一个长为n的对称01串。alice和bob两个人轮流操作。如果当前状态为对称,那么必须选一个0位改为1;如果不对称,可以选一个0位改为1,也可以reverse一下,但是如果上一次操作对方以及reverse过了,那此次就不能reverse。
题解:首先,reverse对于最终结果没用,直接看成跳过操作。其次,由于是对称情况,所以串里面的1字符也没用。如果原来的串有x个0y个1,那么可以把原串看成x个0的串。
接下来分情况讨论:
如果x为偶数:
从x=2开始看,先手alice必须走一步(因为是对称),走完一步后局面不对称,bob可以跳过,alice不得不走下一步,游戏结束。此时先手alice比后手bob多走了两步。后手bob赢。
接着看x>2的情况。对于局面x,alice必须走一步,bob可以走alice对称的位子,从而局面转化为了x-2的对称局面;接着alice不得不因为对称继续走一步,bob走对称位子,局面转化为x-4;...;
以此类推,一直持续到局面2,此时alice走了之后bob可以不走。因此最后局面是 alice比bob多走两步。后手bob赢。
如果x为奇数:
从x=1开始看,先手alice走一步,结束;alice输;
从x>3开始看,先手alice必走一步,走哪一步?:
如果走正中间mid位置,局面又转化为了没结束对称局面,此时对称下先手为bob,后手为alice。那么最终alice多走了开始的第一步,但是对称局面下可以少走两步。最终情况alice少走一步。alice赢。
总结:
x为偶数,后手必赢
x为奇数。如果x为1,后手必赢;反之先手必赢。
#include<iostream> #include<algorithm> #include<vector> #include<map> #include<cmath> #include<cstring> using namespace std; const int mx=1e3+10; const int inf=1<<30; typedef long long ll; void solve(){ ll n; scanf("%lld", &n); for(ll i=1;i<=n;i++){ ll v; scanf("%lld", &v); char s[mx]; scanf("%s", s); for(ll j=0;j<strlen(s);j++){ if(s[j]==‘1‘)v--; } if(v&1){ if(v == 1){ printf("BOB\n"); } else{ printf("ALICE\n"); } } else{ printf("BOB\n"); } } } int main(){ solve(); return 0; }
Codeforces Round #721 (Div. 2)
原文:https://www.cnblogs.com/ReflexFox/p/14797250.html