AtCoder Beginner Contest 160题解

Posted johnran

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 160题解相关的知识,希望对你有一定的参考价值。

A. 签到题1。

技术图片
#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<0|ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){res=res*10+ch-0;ch=getchar();}
    return res*f;
}

const int MAXN = 200005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int main(){
    string s;cin>>s;
    int ok1=s[2]==s[3];
    int ok2=s[4]==s[5];

    if(ok1&&ok2)cout<<"Yes";
    else cout<<"No";

    return 0;
}
View Code

B. 签到题2。

技术图片
#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<0|ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){res=res*10+ch-0;ch=getchar();}
    return res*f;
}

const int MAXN = 200005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int main(){
    int x;x=read();
    int ans=(x/500)*1000;
    ans+=(x-(x/500)*500)/5*5;
    cout<<ans;

    return 0;
}
View Code

C. 题意,给你一个环和一些点,可以从任意一个点出发,走遍所有点最短路程。

  显然可以丢弃一段,枚举是哪一段即可。

技术图片
#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<0|ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){res=res*10+ch-0;ch=getchar();}
    return res*f;
}

const int MAXN = 200005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int k, n;
int A[MAXN];

int main(){
    k=read();n=read();

    for(int i=0;i<n;++i)A[i]=read();

    int mx=0;

    for(int i=0;i<n;++i){
        if(i==n-1){
            mx=max(mx,k-A[n-1]+A[0]);
        }else{
            mx=max(mx,A[i+1]-A[i]);
        }
    }

    cout<<k-mx;

    return 0;
}
View Code

D. 题意,给一条链,和一条额外的边,问长度为1:N-1的最短路有多少条?

  O(n^2)枚举。

技术图片
#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<0|ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){res=res*10+ch-0;ch=getchar();}
    return res*f;
}

const int MAXN = 2005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int ans[MAXN];

int main(){
    int n, x, y;
    n=read();x=read();y=read();

    for(int i=1;i<=n;++i){
        for(int j=i+1;j<=n;++j){
            int t=min(j-i,1+abs(i-x)+abs(j-y));
            ++ans[t];
        }
    }

    for(int i=1;i<=n-1;++i){
        cout<<ans[i]<<endl;
    }

    return 0;
}
View Code

E. 要吃掉X个红苹果,Y个绿苹果,还有c个无色的苹果,每一个都有一定的价值,问最后最大价值?

  分别排序之后,把前X大和前Y大的丢进堆里,对无色的正向扫,当堆顶部的小于无色的价值时出堆。

技术图片
#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<0|ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){res=res*10+ch-0;ch=getchar();}
    return res*f;
}

const int MAXN = 200005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

int a,b,c;

int x,y;

int A[MAXN], B[MAXN], C[MAXN];

priority_queue<int,vector<int>, greater<int>> q;

int main(){
    x=read();y=read();
    a=read();b=read();c=read();

    for(int i=1;i<=a;++i)A[i]=read();
    for(int i=1;i<=b;++i)B[i]=read();
    for(int i=1;i<=c;++i)C[i]=read();

    sort(A+1,A+1+a);
    sort(B+1,B+1+b);
    sort(C+1,C+1+c);

    LL ans=0;

    for(int i=a;i>=a-x+1;--i)q.push(A[i]), ans+=A[i];
    for(int i=b;i>=b-y+1;--i)q.push(B[i]), ans+=B[i];

    for(int i=c;i>=1;--i){
        if(C[i]>q.top()){
            ans-=q.top();
            q.pop();
            q.push(C[i]);
            ans+=C[i];
        }
    }

    cout<<ans;

    return 0;
}
View Code

F. 给你一颗n个节点的树,依次放入1-n,放置的条件是这条边的另一个点已经放置了数字,求把1分别放置在节点1-n的方案数。

  因为要求把1放在1-n号节点上的方案数,明示了换根dp(或许还有其他做法,但我不会嘿嘿。先考虑以把1放在一号节点的时候怎么数操作数。

  设pre[v]是以v为根的子树的安排方式数。这个时候就是一个简单的乘法原理,先选再放进子树安排。第一次dfs就能处理出所有的pre[]。在换根的时候

  我们首先要考虑到以u的儿子v为根的时候,我们首先要得到u作为v子树的pre[u]。这个显然(可能需要在纸上稍微写一下,原理就是先选再排)是ans[u]/(pre[v]*C(n-1,sz[v])),知道这个之后,得到ans[v]不过就是为u

  这个子树重新选取一些数字而已,这个显然是C(n-1,n-sz[v])种可能。根据计算u答案的方法,直接套用到v上即可,具体见代码。

技术图片
#include<bits/stdc++.h>

#define fi first
#define sd second
#define lson (nd<<1)
#define rson (nd+nd+1)
#define PB push_back
#define mid (l+r>>1)
#define MP make_pair
#define SZ(x) (int)x.size()

using namespace std;

typedef long long LL;

typedef vector<int> VI;

typedef pair<int,int> PII;

inline int read(){
    int res=0, f=1;char ch=getchar();
    while(ch<0|ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){res=res*10+ch-0;ch=getchar();}
    return res*f;
}

const int MAXN = 200005;

const int MOD = 1000000007;

void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
int mulmod(int a, int b){return 1ll*a*b%MOD;}

#define go(e,u) for(int e=head[u];e;e=Next[e])
int to[MAXN<<1],Next[MAXN<<1],head[MAXN],tol;

void add_edge(int u,int v){
    Next[++tol]=head[u];to[tol]=v;head[u]=tol;
    Next[++tol]=head[v];to[tol]=u;head[v]=tol;
}

int ans[MAXN];

int cnt[MAXN], pre[MAXN], tp[MAXN];

int sz[MAXN];

int fac[MAXN], inv[MAXN], n;

int powmod(int x, int y){
    int res=1;
    while(y){
        if(y&1)res=1ll*res*x%MOD;
        y>>=1;
        x=1ll*x*x%MOD;
    }

    return res%MOD;
}

void init(){
    fac[1]=fac[0]=1;
    for(int i=2;i<=n;++i)fac[i]=1ll*fac[i-1]*i%MOD;
    inv[0]=inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=1ll*MOD-1ll*MOD/i*inv[MOD%i]%MOD;
    for(int i=2;i<=n;++i)inv[i]=1ll*inv[i-1]*inv[i]%MOD;
}

int C(int n, int m){
    return 1ll*fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}

void dfs1(int u, int f){
    sz[u]=1;pre[u]=1;
    go(e,u){
        int v=to[e];
        if(v==f) continue;
        dfs1(v,u);
        sz[u]+=sz[v];
        pre[u]=1ll*pre[u]*pre[v]%MOD*C(sz[u]-1,sz[v])%MOD;
    }
}

void dfs2(int u, int f){
    ans[u]=1ll*tp[u]*pre[u]%MOD*C(n-1,n-sz[u])%MOD;
    go(e,u){
        int v=to[e];
        if(v==f)continue;
        tp[v]=1ll*ans[u]*powmod(1ll*pre[v]*C(n-1,sz[v])%MOD,MOD-2)%MOD;
        dfs2(v,u);
    }
}

int main(){
    n=read();
    for(int i=1;i<n;++i){
        int u, v;
        u=read();
        v=read();
        add_edge(u,v);
    }

    init();
    dfs1(1,0);
    tp[1]=1;
    dfs2(1,0);

    for(int i=1;i<=n;++i)cout<<ans[i]<<endl;

    return 0;
}
/*
8
1 2
2 3
3 4
3 5
3 6
6 7
6 8


40
280
840
120
120
504
72
72

*/
View Code

 

以上是关于AtCoder Beginner Contest 160题解的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Beginner Contest 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242