A - A+B Again?
题意:给定一个两位数,求位数之和
分析:模拟即可
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; void sol(){ int n;cin>>n; ll ans=0; while(n>0){ ans+=n%10; n/=10; } cout<<ans<<endl; } int main(){ int t;cin>>t; while(t--)sol(); return 0; }
B - Card Game
题意:SU拿了a1和a2的牌,SL拿了b1和b2的牌,他们都不知道牌是什么,每次每人翻开一张,牌大的胜利,牌相同平局,共两回合,如果获胜回合数多则胜利,求SU能获胜几把。
分析:模拟SU获胜的情况即可。1.平局加获胜 2.获胜加获胜
#include<bits/stdc++.h> using namespace std; typedef long long ll; void sol(){ int a1,a2,b1,b2;cin>>a1>>a2>>b1>>b2; int ans=0; if((a1>b1&&a2>b2)||(a1==b1&&a2>b2)||(a2==b2&&a1>b1))ans++; if((a1>b2&&a2>b1)||(a1==b2&&a2>b1)||(a2==b1&&a1>b2))ans++; cout<<ans*2<<endl; } int main(){ int t;cin>>t; while(t--)sol(); return 0; }
C - Showering
题意:在m分钟内,亚历克斯有s秒洗澡,他在li-ri秒里不能洗澡,请问他能洗上澡吗
分析:先将任务块按l从小到大排序,然后算当前时间与下一个任务的li的差值,如果大于等于s他就可以洗澡,如果不行他就让当前时间到任务块的ri。最后如果当前时间小于m的话,在判断当前时间与m的差值就好啦
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; struct A{ int l,r; }a[N]; bool cmp(A x,A y){ return x.l<y.l; } void sol(){ ll n,s,m;cin>>n>>s>>m; for(int i=1;i<=n;i++){ cin>>a[i].l>>a[i].r; } sort(a+1,a+n+1,cmp); ll cur=0; for(int i=1;i<=n;i++){ if(a[i].l-cur>=s&&a[i].l<=m&&cur<=m){ cout<<"YES"<<endl; return; } else{ cur=a[i].r; } } if(cur<=m){ if(m-cur>=s){ cout<<"YES"<<endl; return; } } cout<<"NO"<<endl; } int main(){ int t;cin>>t; while(t--)sol(); return 0; }
D. Slavic's Exam
题意:给定字符串s,t,将s里的问号替换,使得t成为s的子字符串,可以不连续。
分析:每次从si里寻找tj,如果si是问号,就把si替换成tj,tj每次找到相应字符就让j++,只要t全部遍历了一遍就说明t是s的子字符串。输出s字符串即可。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; void sol(){ string s,t;cin>>s>>t; int lens=s.size(),lent=t.size(); if(lens==lent){ for(int i=0;i<lens;i++){ if(s[i]<='z'&&s[i]>='a'&&s[i]!=t[i]){ cout<<"NO"<<endl; return; } else if(s[i]=='?'){ s[i]=t[i]; } } cout<<"YES"<<endl; for(int i=0;i<lens;i++)cout<<s[i]; cout<<endl; } else{ int j=0; t[lent]=t[lent-1]; for(int i=0;i<lens;i++){ if(s[i]=='?'){ s[i]=t[j]; if(j<lent)j++; } else if(s[i]==t[j]){ if(j<lent)j++; } } if(j==lent){ cout<<"YES"<<endl; for(int i=0;i<lens;i++){ cout<<s[i]; } cout<<endl; } else{ cout<<"NO"<<endl; } } } int main(){ int t;cin>>t; while(t--)sol(); return 0; }
E - Triple Operations
题意:有一组数组,从l到r,每次挑选两个数字x和y,让x=x*3,y=floor(y/3),求将所有数字变为0的最少操作次数
分析:可以算出每个数向下取整需要多少次才能变为0,用a数组记录。然后a数组变成前缀和以便后面计算。可以先将最小的数字变为0,就是(al-a(l-1)),同时后面会有一个数数字进行(al-a(l-1))次×3。剩下都当成y,x是0,也就是加上每个数变成0的操作次数,并且刚才还有一个数字进行(al-a(l-1))次×3,加上去就好啦
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; ll a[N]; void sol(){ int l,r;cin>>l>>r; cout<<a[r]-a[l]+(a[l]-a[l-1])*2<<endl; } int main(){ int cnt=1; for(int i=1;i<=2e5;i++){ if(i==pow(3,cnt)){ cnt++; } a[i]=cnt; } a[0]=0; for(int i=1;i<=2e5;i++){ a[i]+=a[i-1]; } int t;cin>>t; while(t--)sol(); return 0; }
F - Expected Median
题意:有一个01字串,每次选k个数字,求排完序的第(k+1)/2个元素相加。
分析:因为每次选k个数字不用连续,也就是任选k个数字,记录1的个数y和0的个数z就好了,只要i的个数大于l的个数(i是拿了几个1,l是拿了几个0),所以每次从y里面拿i个*从z里面拿l个相加即可。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; const ll mod=1e9+7; ll f[N],invf[N]; ll ksm(ll a,ll b){ ll res=1%mod; while(b){ if(b&1) res=res*a%mod; a=a*a%mod; b>>=1; } return res; } ll inv(ll x){ return ksm(x,mod-2); } ll C(ll a,ll b){ return f[a]*invf[b]%mod*invf[a-b]%mod; } void init(){//写主函数里 f[0]=invf[0]=1; for(int i=1;i<N;i++){ f[i]=f[i-1]*i%mod; invf[i]=inv(f[i])%mod; } } void sol(){ ll n,k;cin>>n>>k; ll z=0,y=0; for(int i=1;i<=n;i++){ ll x;cin>>x; if(x==0)z++; else y++; } ll l=k-min(y,k); ll ans=0; for(ll i=min(y,k);i>=1;i--){ if(i>=l&&l<=z){ ans+=C(y,i)*C(z,l); ans%=mod; l++; } else{ break; } } cout<<ans%mod<<endl; } int main(){ init(); int t;cin>>t; while(t--)sol(); return 0; }