牛客网月赛24--ABC

牛客月赛24比赛链接

A题

题目描述

xb有m种石子,每种无限个,Ta想从这些石子中取出n个,并按顺序排列起来,为了好看,相邻的石子不能相同。xb想知道有多少种排列的方法。

输入描述:

第一行有两个正整数n,m。

输出描述:

第一行一个整数,表示在m种石子中取出n个的排列方案数模1000000007后的值

n个位置  那么第一个位置有m种选择  不能重复  所以第二个位置有m-1个选择   第三个也是m-1

所以 ans=m*(m-1)^(n-1)

代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const int maxn=10000;
ll mod=1000000007;
ll pow_mod(ll x,ll n){
    ll res=1;
    while(n){
        if(n&1)
        res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}
int n,m;
int main(){
    scanf("%lld%lld",&n,&m);
    ll ans=m*pow_mod(m-1,n-1)%mod;
    printf("%lld",ans);
}

B题

题目描述

    传说,凤凰是百鸟之王。有一天,凤凰要召开百鸟大会,百鸟国是一个由n个节点组成的树,每个节点有一只鸟,开会的节点定在1号节点。每只鸟可以花费1s通过一条边,由于每根树枝(边)的载重有限,只允许一只鸟同时通过。作为会议的策划师,HtBest想知道百鸟国的所有鸟在1点集合最少需要多少秒。

输入描述:

第一行有一个正整数n,表示百鸟国节点个数。
接下来n-1行,第i行两个正整数ai,bi用空格隔开,表示树上节点ai,bi之间有一条边。

输出描述:

第一行一个整数,表示集合最少需要的时间。

并查集 代码

#include<stdio.h>
const int maxn=1e6+7;
int fa[maxn],cnt[maxn];
int Find(int x){
    return fa[x]==x?x:fa[x]=Find(fa[x]);
}
void Merge(int x,int y){
    int p1=Find(x),p2=Find(y);
    if(p1!=p2) fa[p1]=p2;
}
int n,x,y,ans;
int main(){
    scanf("%d",&n);
    for(int i=0;i<=n;i++)fa[i]=i;
    for(int i=0;i<n-1;i++){
        scanf("%d%d",&x,&y);
        if(x!=1&&y!=1)Merge(x,y);
    }
    for(int i=1;i<=n;i++){
        int flag=Find(i);
        cnt[flag]++;
        if(ans<cnt[flag])ans=cnt[flag];
    }
    printf("%d\n",ans);
    return 0;
}

C题

题目描述

    PH试纸,是一种检测酸碱度的试纸,试纸红色为酸性,蓝色为碱性。

    HtBest有一个PH试纸,试纸被分成了n段,每一段都可以被染色成红色或者蓝色,WHZ在试纸的每一段上都染为一种颜色,HtBest有m个询问,对于每个询问,Ta想知道某种颜色第qi次在什么地方出现。

输入描述:

第一行有两个正整数n,m。
第二行有n个字母(‘R’或’B’),每个第i个字母表示PH试纸第i段的颜色。
接下来m行,第i行有一个大写字母 ci(‘R’或’B’)和一个正整数qi ,用空格隔开,表示查询颜色ci 第qi 次出现的位置。

输出描述:

共m行,第i行一个整数,表示查询结果,若颜色ci出现次数少于qi次,则输出-1,否则输出颜色qi第ci次出现的位置。

用两个数组   查找复杂度优化为O(1)

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=1e6+7;
int r[maxn],b[maxn],n,m;
char ch[maxn];
int k,cntr,cntb;
int main(){
	scanf("%d%d",&n,&m);
	scanf("%s",ch);
	for(int i=0;i<n;i++){
		if(ch[i]=='R'){
			cntr++;r[cntr]=i;
		}
		else{
			cntb++;b[cntb]=i;
		}
	}
	while(m--){
		char str[5];
		scanf("%s%d",str,&k);
		if(str[0]=='R'){
			if(cntr<k) printf("-1\n");
			else printf("%d\n",r[k]+1);
		}
		else{
			if(cntb<k) printf("-1\n");
			else printf("%d\n",b[k]+1);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/holly_Z_P_F/article/details/81583754
今日推荐