CodeForce2019-12-28Div2补题

注意一:当值作下标时注意是否越界

注意二:开静态数组时注意是1e5+3还是1e6+3

注意三:求和SUM时注意是否需要ull

 

A题:给出RGB三色块数,问能否排成一列且相邻块异色

解:如果有其中两个数之和比第三个数小2及以上则不能

#include<bits/stdc++.h>

using namespace std;

int main(){

    int t;cin>>t;

    while(t--){

        int r,g,b;

        cin>>r>>g>>b;

        if(r+g<b-1)cout<<"No"<<endl;

        else if(r+b<g-1)cout<<"No"<<endl;

        else if(g+b<r-1)cout<<"No"<<endl;

        else cout<<"Yes"<<endl;

    }

    return 0;

}

 

B题:小明要依次背N首诗,每首诗用时Ai秒。妈妈听小明背诗,每背完一首得到一份礼物,但只听前S秒,现小明可以删一首诗不背,问他要得到最多礼物应删哪首诗,可不删

解:遍历一次,求前缀和同时维护当前出现的用时最长的诗的用时及下标

当前缀和大于S时,直接输出当前出现的用时最长的诗的下标

当前缀和等于S时,如果正好是最后一首,输出0,即不删;如果维护的用时最长的诗的用时比下一首诗的用时短则也是0,若是更长则输出用时最长的诗的下标

#include<bits/stdc++.h>

using namespace std;

int a[100003];

int main(){

    int t;cin>>t;

    while(t--){

        int n,s;cin>>n>>s;

        for(int i=1;i<=n;i++)cin>>a[i];

        int tmp,sum=0,ans=0,mxv=-1;

        for(int i=1;i<=n;i++){

            tmp=a[i];sum+=tmp;

            if(tmp>mxv){

                ans=i;

                mxv=tmp;

            }

            if(sum>s){

                cout<<ans<<endl;

                break;

            }

            if(sum==s){

                if(i==n){

                    cout<<0<<endl;

                    break;

                }

                if(mxv<=a[i+1]){

                    cout<<0<<endl;

                    break;

                }

                cout<<ans<<endl;

                break;

            }

        }

        if(sum<s)cout<<0<<endl;

    }

    return 0;

}

 

C题:现有一堆礼物,以栈形式存放,按给定编号顺序拿出礼物,若编号i礼物是栈中从栈顶往下数第K+1个,则需要操作k+1次出栈和K次入栈共2K+1次操作,他上面的K个礼物的顺序在入栈时可以随意调动,问全部礼物拿出需要的最小总操作数

解:依次出拿礼物,维护前面已经访问到的最大深度,当当前要拿出的礼物的深度比原先的小,就直接ans++,因为他可以被放到栈顶,否则就是2*(深度值-i-1)+1;,即2K+1,此处的深夜K是深度值-i,i是轮数,从0起,第i轮时已有i个礼物被拿走,故是深度值-i

#include<bits/stdc++.h>

using namespace std;

int a[100003];

int main(){

    int t;cin>>t;

    while(t--){

        int m,n,tmp,mx=0;

        unsigned long long ans=0;

        cin>>m>>n;

        for(int i=1;i<=m;i++){

            cin>>tmp;

            a[tmp]=i;

        }

        for(int i=0;i<n;i++){

            cin>>tmp;

            if(a[tmp]>mx){

                ans+=2*(a[tmp]-i-1)+1;

                mx=a[tmp];

            }

            else ans++;

        }

        cout<<ans<<endl;

    }

    return 0;

}

 

D题:有N人,每人有N属性,现随机选两人(可重复),问第一人属性中随机选一个且第二人有的概率

解:求每个属性被抽到的概率,再每个属性有人拥有的概率(即有多少人有),得相乘之和

#include<bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;

const ull N=1e6+3,mod=998244353;

ull p[N],cnt[N],inv[N];

int main(){

    inv[1]=1;for(ull i=2;i<N;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod;

    ull n;cin>>n;

    for(ull i=1;i<=n;i++){

        ull m;cin>>m;

        ull x=1LL*inv[n]*inv[m]%mod;

        for(ull j=1;j<=m;j++){

            ull tmp;cin>>tmp;

            cnt[tmp]++;

            p[tmp]=(p[tmp]+x)%mod;

        }

    }

    ull ans=0;

    for(ull i=1;i<N;i++)ans=(ans+p[i]*cnt[i]%mod*inv[n]%mod)%mod;

    cout<<ans<<endl;

    return 0;

}

 

补充:快递幂求逆元

#include <iostream>

using namespace std;

ll fmx(ll a,ll p,ll mod){

    a%=mod;

    ll ans=1;

    while(p){

        if(p&1)ans=(ans*a)%mod;

        a=(a*a)%mod;

        p>>=1;

    }

    return ans;

}

int main(){

    ll a,p,mod;cin>>a>>p>>mod;

    cout<<fmx(a,p,mod)<<endl;//求a^p模mod

    cout<<fmx(a,mod-2,mod)<<endl;//求a^(p-2)模mod这,就是模mod意义下a的逆元

    return 0;

}

 

补充:两个不等长有序数组的中位数求法

int find_median(int *A,int *B,int m,int n,int s,int t){

    int p=(s+t)/2,c=(m+n-1)/2;/* 有多少个数小于下中位数 */

    if(s>t)return find_median(B,A,n,m,0,n-1);/* 如果下中位数不在A中,就从数组B找 */

    else if(A[p]>=B[c-p-1]&&A[p]<=B[c-p])return A[p];/* 数组A中有p个数小于A[p], 当且进当数组B中有c-p个数小于A[p], A[p]才是中位数 */

    else if(A[p]<B[c-p-1])return find_median(A,B,m,n,p+1,t);/* A[p]太小了,从数组A中找一个更大的数尝试 */

    else return find_median(A,B,m,n,s,p-1);/* A[p]太大了,从数组A中找一个更小的数尝试 */

}

int main(){

    int A[]={1,3,5,7,9};

    int B[]={2,4,6,8,10};

    int m = sizeof(A)/sizeof(int);

    int n = sizeof(B)/sizeof(int);

    printf("%d\n", find_median(A, B, m, n, 0, m-1));/* 从数组A和B中找下中位数 */

    return 0;

}

猜你喜欢

转载自blog.csdn.net/cj1064789374/article/details/103750189