Codeforces Round #721 (Div. 2)
作者:互联网
2021.5.20
A
题意:给一个整数n,求出最大的k,其中n&(n-1)&...&k=0
题解:只需要让n每次递减的数每个二进制位都有存在0,可想k就是n的最高位为1其他位都为0的数m-1,这样可以保证每位二进制位都有0
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
ll t,n;
cin>>t;
while(t--)
{
cin>>n;
if(n==1)
cout<<0<<endl;
else if(n==2)
cout<<1<<endl;
else{
ll k=1;
while(k<n){
k*=2;
}
if(k!=n)
k/=2;
cout<<k-1<<endl;
}
}
return 0;
}
B1
题意:规则:每次只能有两个操作:1、把0变成1花费1 ;2、若现在字符串的状态不为回文串,那可以把子符串颠倒,若为回文串或者上一回合用了翻转,则只能用操作1,不能翻转。给一个回文字符串,只包含0和1,ALICE先手,BOB后手,最后把字符串都变为1谁花费的多,一样的话输出“DRAW”。
题解:只需判断子串串0的个数,若无0肯定就是平局,如果0的个数为奇数,那么证明字符串长度为奇数,且最中间的为0,这种情况如果只有1个0那么肯定是先手输,如果大于1,则后手必输(比如“10001”,先手拿掉中间的,字符串又是回文,后手只能拿花费1,然后先手翻转,后手又只能花1),如果0的个数为偶数,那么先手必输。(最后剩两个先手每次必花费1,后手翻转,最后一个又只能先手花费1)
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
int t,n;
string s;
cin>>t;
while(t--)
{
cin>>n>>s;
int k0=0,k1=0,len=s.size();
for(int i=0;i<n;i++)
{
if(s[i]=='0')
k0++;
else
k1++;
}
if(k0==0)
cout<<"DRAW"<<endl;
else
{
if(k0%2)
{
if(k0==1)
cout<<"BOB"<<endl;
else
cout<<"ALICE"<<endl;
}
else
{
cout<<"BOB"<<endl;
}
}
}
return 0;
}
B2
题意:再B1的基础上,输入的子符串不一定是回文串。
题解:只需枚举出不是先手赢的情况:0个数为2且只有一个不对称的位置,一样是平局,如果是回文串且0的个数是偶数或者0的个数为1,那么就是后手赢,其他情况都是先手赢(先手有拿或者翻转的选择,所以可以去掉自己输的情况,把自己输的情况给后者)
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <cstring>
#include <string>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
int t,n;
string s;
cin>>t;
while(t--)
{
cin>>n>>s;
int dif=0;
for(int i=0;i<(n+1)/2;i++)
{
if(s[i]!=s[n-i-1])
dif++;
}
int num=count(s.begin(),s.end(),'0');
if(!dif&&(num%2==0||num==1))
cout<<"BOB"<<endl;
else if(dif==1&&num==2)
cout<<"DRAW"<<endl;
else
cout<<"ALICE"<<endl;
}
return 0;
}
C
题意:给一个长度为n的整数序列a,其中若整数对 i<j && ai=aj 则这一整数对贡献为1,其中不同子序列若有重复的位置贡献属于不同的贡献,计算序列a的所有子序列的贡献和。
题解:dp[i]的贡献=dp[i-1]的贡献+包含ai这个数的子序列的贡献(前面所有等于ai的数的下标和*后面包含ai还要几个数可以作为子序列)
#include <iostream>
#include <algorithm>
#include <map>
#define ll long long
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
int t,n,x;
cin>>t;
while(t--)
{
cin>>n;
map<int,ll>m;
ll sum=0;
for(int i=1;i<=n;i++)
{
cin>>x;
sum+=m[x]*(n-i+1);
cout<<m[x]*(n-i+1)<<endl;
m[x]+=i;
}
cout<<sum<<endl;
}
return 0;
}
标签:int,个数,cin,Codeforces,先手,721,Div,include,回文 来源: https://blog.csdn.net/weixin_46113968/article/details/117198174