A

知识点:implementation
思路:分别统计A B C D四个字符的个数,然后判断一下就行了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
    ll n,t,i,j,k;
    cin>>t;
    while(t--){
        string s;
        cin>>s;
        int a=0,b=0,c=0,d=0;
        for(i=0;i<4;i++){
            if(s[i]=='A')a++;
            if(s[i]=='B')b++;
            if(s[i]=='C')c++;
            if(s[i]=='D')d++;
        }
        if(d||c>=2)cout<<"failed\n";
        else if(!d&&a>=3)cout<<"sp offer\n";
        else cout<<"offer\n";
    }
}

B

知识点:greedy,game
思路:这道题其实有歧义,应该加一句“每个人都不希望自己出局的前提下,希望出局的人越多越好”。
这样的话,每个人一定会拿“能拿牌最少数量”的那个人,这样这个人就一定会被淘汰掉。
当剩余的人数不大于剩余的 时,就永远不会有人淘汰了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[111111];
int main(){
    ll n,t,i,j,k;
    cin>>n;
    for(i=0;i<n;i++)cin>>a[i];
    sort(a,a+n);
    for(i=0;i<n;i++){
        if(a[i]>=n-i-1)break;
    }
    cout<<n-i;

}

C

知识点:greedy,math
第一天显然是让最大的 翻3倍,剩下的最大的 翻2倍。
从第二天开始,如果继续让最大的 翻3倍,剩下的最大的 翻2倍,那么剩下的人就会被淘汰掉。但是很明显哪怕淘汰了这些人,最终的结果也是最大的。因为淘汰的本就是 最小的那一批,连翻两倍的那部分 都比不过。
所以最终的结果就是让最大的 次3倍,剩下的最大的 次2倍,然后判断一下最后那部分人有没有淘汰掉就可以了(也就是判断 是否是1)。
注意要用快速幂加速。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int mod =1e9+7;
ll power(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}
ll a[111111];
int main(){
   // freopen("tiaoxin.in","r",stdin);
    ll n,m,x,y,t,i,j,k;
    cin>>n>>m>>x>>y;
    for(i=0;i<n;i++)cin>>a[i];
    sort(a,a+n);
    ll res=0;
    if(m==1){
        for(i=n-1;i>=n-x;i--){
            res+=a[i]*3;
        }
        for(i=n-x-1;i>=n-x-y;i--){
            res+=a[i]*2;
        }
        for(;i>=0;i--){
            res+=a[i];
        }
        cout<<res%mod;
        return 0;
    }

    for(i=n-1;i>=n-x;i--){
        res+=a[i]*power(3,m)%mod;
    }
    for(;i>=n-x-y;i--){
        res+=a[i]*power(2,m)%mod;
    }
    cout<<res%mod;
    return 0;


}

D

这道题没过,官方给的题解好像是错的,我稍微云一下题解吧。
可以得出结论,操作1等价于让某个数除以素数 ,操作2等价于让某个数乘以素数 。由于每个素数又是独立的,那么这道题就等价于这样:
已知每个素数 在每个数 里出现的次数,每次可以操作可以让某个数的p的次数加一或减一,求让所有次数相等的最小操作数。
这样答案就很明显了,把所有数中的 的次数变成所有次数的中位数就可以了。这样操作次数就是最小的。下面我分享一下我做题中想到的思路(因为复杂度太大了所以没码)
先筛出所有素数,然后枚举每个素数在每个数中的出现的次数,然后求中位数。
复杂度:线性筛 ,素数个数大致为 ,计算单独一个数的素因子个数为 ,计算中位数复杂度为 ,最终复杂度为 ,总复杂度约为
这样如果 数量级那么我这个思路是可行的,但由于 达到了1e6,所以直接暴毙,码都懒得去码了ORZ
期待出题人更新正确的题解。
upd:出题人已经把题目修改了,让操作2去世,只剩下的操作1。。。emmm。。。不过这样改的话这个题就变得比较水了