一.闲话

由于我太菜了,打不动了就来写题解了

A.A Simple Problem about election

贪心即可

先给自己票数加1,多余的尽量给票数增加后对自己排名无影响的人

如果还有剩,则排名=现在排名+剩下的票数(每给剩余人一票一定会使得自身排名+1)

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
int a[N],b[N];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i){
            scanf("%d",&a[i]);
        }
        ++a[1];--m;
        if(m){
            for(int i=2;i<=n;++i){
                if(a[i]>=a[1]){
                    ++a[i];--m;
                }else if(a[i]+1<a[1]){
                    ++a[i];--m;
                }
                if(!m){
                    break;
                }
            }
        }
        int ans=0;
        for(int i=1;i<=n;++i){
            ans+=(a[i]>=a[1]);
        }
        printf("%d\n",ans+m);
    }
    return 0;
}

B.看到几何脑壳痛,直接跳qwq

C.一道以前做过的后缀数组题,不过忘了qwq,就不想做了qwq(我好菜啊)

D.Deploy the medical team

超简单的数学题,先从m名队长中选一名作队长(因为队长唯一,所以无重复),保证队伍一定有队长,剩下的随便选

答案即:

套个快速幂即可~

代码:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
inline int ksm(int x,int y){
    int ans=1;
    while(y){
        if(y&1){
            ans=(1LL*ans*x)%mod;
        }
        x=(1LL*x*x)%mod;
        y>>=1;
    }
    return ans;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        int ans=(1LL*m*ksm(2,n-1))%mod;
        printf("%d\n",ans);
    }
    return 0;
}

E盲猜差分约束,然而我spfa超时了qwq(估计有玄学的做法qwq我好菜啊)

F.Figure out the sequence

表示第i次变换后,编号为j的字母的个数(我们最好将'A'-'Z'依次编为0-25,'a'-'z'依次编为26-51,这样方便输出)

读题目后,发现和菲波拉契很像(只是把数字的加法变成了字符串的加法而已)

所以,有递推式:

i=1和2时直接分别统计s,t串即可

代码:

#include<bits/stdc++.h>
using namespace std;
int dp[41][52];
int main(){
    string x,y;
    cin>>x>>y;
    int n;
    scanf("%d",&n);
    int len=x.size(),ten=y.size();
    for(int i=0;i<len;++i){
        if(x[i]>='a'&&x[i]<='z'){
            ++dp[1][x[i]-'a'+26];
        }else{
            ++dp[1][x[i]-'A'];
        }
    }
    for(int i=0;i<ten;++i){
        if(y[i]>='a'&&y[i]<='z'){
            ++dp[2][y[i]-'a'+26];
        }else{
            ++dp[2][y[i]-'A'];
        }
    }
    for(int i=3;i<=n;++i){
        for(int j=0;j<52;++j){
            dp[i][j]=dp[i-1][j]+dp[i-2][j];
        }
    }
    for(int i=0;i<52;++i){
        if(dp[n][i]){
            if(i<26){
                printf("%c: %d\n",char(i+'A'),dp[n][i]);
            }else{
                printf("%c: %d\n",char(i+'a'-26),dp[n][i]);
            }
        }
    }
    return 0;
}

G.Game Strategy

直接模拟枚举即可,我们枚举最后剩下的数就行了,Alice取所有剩下的数中最大的那个方案,Bob取最小的那个方案,当Alice和Bob取的数确定时,Cindy取的数就固定了,我们直接算一遍就行了

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=101;
int a[N],b[N],c[N];int n;
inline int dfs2(int now){
    int ans=2e9;
    for(int i=1;i<=n;++i){
        if(abs(now+c[i])<abs(ans)){
            ans=now+c[i];
        }else if(abs(now+c[i])==abs(ans)){
            ans=max(ans,now+c[i]);
        }
    }
    return ans;
}
inline int dfs1(int now){
    int res=2e9;
    for(int i=1;i<=n;++i){
        res=min(res,dfs2(now+b[i]));
    }
    return res;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    for(int i=1;i<=n;++i){
        scanf("%d",&c[i]);
    }
    int ans=-2e9;
    for(int i=1;i<=n;++i){//枚举Alice
        ans=max(ans,dfs1(a[i]));
    }
    printf("%d",ans);
    return 0;
}

H.Hinnjaku

这题真有趣(滑稽)

直接模拟字符串就行了

先判断是否有zawaluduo,有的话,就按题目说的将对方秒掉(记得优先Dio)

然后,再判断是否可以attact对方

如果有一个人Hp=0的话,退出然后比较Hp大小即可

代码:

#include<bits/stdc++.h>
using namespace std;
char kil[10]={'z','a','w','a','l','u','d','u','o'};
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,H;
        scanf("%d%d",&n,&H);
        string x,y;
        cin>>x>>y;
        int LH=H,RH=H;
        for(int i=2;i<n;++i){
            bool kil1=1,kil2=1;
            if(i>=8){
                for(int j=i-8;j<=i;++j){
                    kil1&=(x[j]==kil[j-i+8]);
                    kil2&=(y[j]==kil[j-i+8]);
                }
            }
            if(i<8){
                kil1=kil2=0;
            }
            if(kil2){
                LH=0;
                break;
            }
            if(kil1){
                RH=0;
                break;
            }
            int ht1=0,ht2=0;
            ht1=(x[i-2]=='o'&&x[i-1]=='r'&&x[i]=='a');
            if(i>2){
                ht2=(y[i-3]=='m'&&y[i-2]=='u'&&y[i-1]=='d'&&y[i]=='a');
            }
            RH-=ht1,LH-=ht2;
            if(!LH||!RH){
                break;
            }
        }
        if(LH!=RH){
            if(LH>RH){
                puts("Wryyyyy");
            }else{
                puts("Hinnjaku");
            }
        }else{
            puts("Kono Dio da");
        }
    }
    return 0;
}

I.Interesting Matrix Problem

简单数学题,考虑二分答案,那么,我们只需要尽快计算出矩形中小于等于x的数字的个数

注意到,(i,j)的值为i*j

那么,我们有:

第i行中,小于等于x的数字的个数为:

所以答案就是:

这样就是个明显的整数分块模板题了。。。

(之前为了防止bug,代码中多个地方用了min,有些其实并不需要)
代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,q;
inline int calc(int x){//矩阵中值小于等于x的数的个数
    int ans=0;
    //ans=sum(i=1,n,min(m,[x/i]))
    //=>整数分块
    for(int r,l=1;l<=min(x,n);l=r+1){
        r=min(n,x/(x/l));
        ans+=(min(m,x/l)*(r-l+1));
    }
    return ans;
}
signed main(){
    scanf("%lld%lld%lld",&n,&m,&q);
    while(q--){
        int x;
        scanf("%lld",&x);
        int l=1,r=x,ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(calc(mid)>=x){
                ans=mid;r=mid-1;
            }else{
                l=mid+1;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

J.Jogging along the Yangtze River

首先,发现输入数字只有一个,那么。。。肯定找规律啊(滑稽)

写了个暴力,打了个表:

2,6,22,90,394

观测了一会儿,没想法,直接上OEIS

发现规律:

预处理出

再枚举i即可计算

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1,mod=998244353;
int C[N],g[N];
int main(){
    C[0]=g[0]=g[1]=1;
    for(int i=2;i<N;++i){
        g[i]=(1LL*g[mod%i]*(mod-mod/i))%mod;
    }
    int x;
    scanf("%d",&x);
    for(int i=1;i<=x;++i){
        C[i]=(1LL*C[i-1]*(x-i+1))%mod;
        C[i]=(1LL*C[i]*g[i])%mod;
    }
    int now=1;int ans=0;
    for(int i=1;i<=x;++i){
        now=(2LL*now)%mod;
        ans=(ans+((1LL*now*((1LL*C[i]*C[i-1])%mod))%mod))%mod;
    }
    ans=(1LL*ans*g[x])%mod;
    cout<<ans;
    return 0;
}