牛客练习赛24 A B C D E F

A
1 n=1 的情况,只有 m 种符合情况的排列方法。
2 m=1 n>1 的情况,没有符合情况的排列方法。
3 m>1 n>1 的情况,有 m*(m-1)^(n-1) 种符合情况的排列方法。

代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=100000+100;
const ll mod=1e9+7;

ll mypow(ll a,ll b){

    ll sum=1;
    while(b){

        if(b&1) sum=sum*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return sum;
}
int main(){

    int n,m;
    scanf("%d%d",&n,&m);
    if(n==1){

        printf("%d",m);
    }
    else if(m==1) printf("0\n");
    else{

        printf("%lld\n",m*mypow(m-1,n-1)%mod);
    }
} 

B
仔细想一想,挺简单的,最少的秒数就是最多结点数的以根的孩子结点为根的子树。

代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=1000000+100;

int head[maxn],tot;
struct Edge{

    int to,next;
}edge[maxn<<1];

int son[maxn];
int Max;

void DFS(int u,int fa){

    son[u]=1;
    for(int i=head[u];i!=-1;i=edge[i].next){

        Edge e=edge[i];
        int v=e.to;
        if(v==fa) continue;
        DFS(v,u);
        son[u]+=son[v];
        if(u==1) Max=max(Max,son[v]);
    }
}

int main(){

    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) head[i]=-1;
    for(int i=1;i<n;i++){

        int u,v;
        scanf("%d%d",&u,&v);
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
        edge[tot].to=u;
        edge[tot].next=head[v];
        head[v]=tot++;
    }
    DFS(1,-1);
    printf("%d\n",Max); 
}

C
水题,具体看代码。

代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=1000000+100;

int a[maxn],atot;
int b[maxn],btot;

char str[maxn];

int main(){

    int n,m;
    scanf("%d%d",&n,&m);
    getchar();
    scanf("%s",str);
    for(int i=0;i<n;i++){

        if(str[i]=='B') a[++atot]=i+1;
        else b[++btot]=i+1;
    }
    while(m--){

        char tmp;
        int k;
        getchar();
        scanf("%c %d",&tmp,&k);
        if(tmp=='B' && k>atot) printf("-1\n");
        else if(tmp=='B') printf("%d\n",a[k]);
        else if(k>btot) printf("-1\n");
        else printf("%d\n",b[k]);

    }
}

D
求到根结点最远的距离即可

代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=50000+100;

int head[maxn],tot;
struct Edge{

    int to,next;
}edge[maxn];

int dis[maxn],len[maxn];
int du[maxn];
int Max;

void DFS(int u,int fa){

    for(int i=head[u];i!=-1;i=edge[i].next){

        Edge e=edge[i];
        int v=e.to;
        if(v==fa) continue;
        dis[v]=dis[u]+len[v];
        DFS(v,u);
        Max=max(Max,dis[v]);
    }
}

int main(){

    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) head[i]=-1;
    for(int i=1;i<n;i++){

        int u,v,leng;
        scanf("%d%d%d",&u,&v,&leng);
        edge[tot].to=u;
        edge[tot].next=head[v];
        head[v]=tot++;
        len[u]=leng;
        du[u]++;
    }
    int root;
    for(int i=1;i<=n;i++) if(du[i]==0) root=i;
    dis[root]=0;
    DFS(root,-1);
    printf("%d\n",Max);
}

E
先建图,跑一遍最短路即可

代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int>P;
const int maxn=10000+100;
const int INF=0x3f3f3f3f;

int head[maxn],tot;
struct Edge{

    int to,next,len;
}edge[maxn<<1];

int dis[maxn];
bool vis[maxn];

void Dijkstra(){

    dis[0]=0;
    priority_queue<P,vector<P>,greater<P> >que;
    que.push(P(0,0));
    while(!que.empty()){

        P p=que.top();
        que.pop();
        int u=p.second;
        if(vis[u]) continue;
        for(int i=head[u];i!=-1;i=edge[i].next){

            Edge e=edge[i];
            int v=e.to;
            if(!vis[v] && dis[v]>dis[u]+e.len){

                dis[v]=dis[u]+e.len;
                que.push(P(dis[v],v));
            }
        }
    }
}

int main(){

    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++) head[i]=-1,vis[i]=false,dis[i]=INF;
    for(int i=0;i<n;i++){

        edge[tot].to=i+1;
        edge[tot].len=1;
        edge[tot].next=head[i];
        head[i]=tot++;

        edge[tot].to=i;
        edge[tot].len=1;
        edge[tot].next=head[i+1];
        head[i+1]=tot++;
    }
    for(int i=1;i<=m;i++){

        int u,v;
        scanf("%d%d",&u,&v);
        edge[tot].to=v;
        edge[tot].len=1;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    Dijkstra();
    printf("%d\n",dis[n]);
}

F
完全背包,竟然这么水。。。
这次没有难题,我竟然能AK,是什么鬼!!!

代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn=100000+100;
const int mod=19260817;

int dp[maxn],ans[maxn];

int main(){

    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&ans[i]);
    dp[0]=1;
    for(int i=1;i<=n;i++){

        for(int j=ans[i];j<=m;j++) dp[j]=(dp[j]+dp[j-ans[i]])%mod;
    }
    int sum=0;
    for(int i=1;i<=m;i++) sum=(sum+dp[i])%mod;
    printf("%d\n",sum); 
}

猜你喜欢

转载自blog.csdn.net/qq_37960603/article/details/81570281