牛客练习赛24

A.石子列阵

题目描述

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

输入描述:

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

输出描述:

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

 

示例1

输入

1 1

输出

1

示例2

输入

2 3

输出

6

示例3

输入

3 3

输出

12

解题:排列组合一下

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

int main()
{
    int n,m;
    while (scanf("%d%d",&n,&m)!=EOF){
    	long long ans=1;
    	for (int j=m,cnt=1;cnt<=n;cnt++){
    		ans*=j%mod;
    		if (j==m)
    		   j--;
    		ans%=mod;
		} 
		printf("%lld\n",ans);
	}
    return 0;
}

B.凤凰

题目描述

    凤凰于飞,翙翙其羽,亦集爰止。

                                        ——《诗经·卷阿》

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

 

输入描述:

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

输出描述:

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

 

示例1

输入

3
1 2
2 3

输出

2

示例2

输入

3
1 2
1 3

输出

1

示例3

输入

4
1 2
2 3
2 4

输出

3

解题:并查集

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int f[maxn],cnt[maxn];
int find(int x){
	return f[x]==x?f[x]:f[x]=find(f[x]);
}
int main()
{
	int n,x,y,ans=0;
    while (scanf("%d",&n)!=EOF){
    	for (int i=0;i<=n;i++)
    	    f[i]=i;
        for (int i=1;i<n;i++){
        	scanf ("%d%d",&x,&y);
        	if (x!=1&&y!=1){
        		x=find(x);
        		y=find(y);
        		f[x]=y;
			}
		} 
		for (int i=0;i<=n;i++)
		    ++cnt[find(i)];
		for (int i=0;i<=n;i++)
		    ans=max(cnt[i],ans);
		printf("%d\n",ans);
	}
    return 0;
}

C.PH试纸
 

题目描述

    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次出现的位置。

 

示例1

输入

2 2
RB
R 1
B 1

输出

1
2

示例2

输入

2 2
BB
R 1
B 2

输出

-1
2

示例3

输入

3 3
BRB
B 1
B 2
R 1

输出

1
3
2

解题:用两个数组来储存所要的R,B个数

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int r[maxn],b[maxn];
char str[maxn];
int main()
{
	int n,m,q,cnt1=0,cnt2=0;
	char sr[10];
	scanf("%d %d",&n,&m);
	scanf("%s",str);
	for (int i=0;i<n;i++){
		if (str[i]=='R'){
			r[++cnt1]=i+1;
		}
		else if (str[i]=='B')
		    b[++cnt2]=i+1;
	}
	while (m--){
	     scanf("%s %d",&sr,&q);
		 if (sr[0]=='R'){
		 	if (r[q]!=0)
		 	   printf("%d\n",r[q]);
		 	else 
		 	   printf("-1\n");
		 }	
		 else if (sr[0]=='B'){
		 	if (b[q]!=0)
		 	   printf("%d\n",b[q]);
		 	else 
		 	   printf("-1\n");
		 }
	}
    return 0;
}

D.插排树
 

题目描述

一年一度的山东省oi夏令营又开始了,每到这个季节,山东的oier们都会欢聚这里,一起学(tuí)习(feì)。当然,为了能更加愉快地学(tuí)习(feì),就少不了要自带电脑,用电便开始成了一种问题,于是便有一种神奇的数据结构诞生了!这就是山东省oi专用数据结构——插排树(如图)

小K为了能更好的学(tuí)习(feì),所以他想尽量的往后做,所以现在请你帮帮他,他最远可以离讲台多远。

已知插排树的根节点在讲台上,有且仅有一个根节点(根节点入度为0),最远距离即所有插排的长度,小K电脑线的长度忽略不计

 

本题良心大样例下载地址: https://kench.co/tree.zip

输入描述:

第一行一个整数n表示有n个节点
然后n-1行,每行三个整数a,b,c,表示插排a是接在插排b上的,插排a的长度为c

输出描述:

一个整数n表示最远距离

 

示例1

输入

9
2 1 2
3 1 2
4 1 1
5 2 3
6 2 1
7 3 1
8 3 4
9 7 5

输出

8

说明

1=>3=>7=>9

题解:自己傻了,看代码估计能理解吧

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
int dist[maxn];
int main()
{
	int n,a,b,c;
	int maxx;
	scanf("%d",&n);
	dist[1]=maxx=0;
	n--;
	while (n--){
		scanf("%d%d%d",&a,&b,&c);
		dist[a]+=dist[b]+c;
		if (maxx<dist[a])
		   maxx=dist[a];
	}
	printf("%d\n",maxx);
    return 0;
}

E.青蛙

题目描述

有一只可爱的老青蛙,在路的另一端发现了一个黑的东西,想过去一探究竟。于是便开始踏上了旅途

一直这个小路上有很多的隧道,从隧道的a进入,会从b出来,但是隧道不可以反向走。

这只青蛙因为太老了,所以很懒,现在想请你帮帮慢,问他最少需要几步才可以到达对面。

将小径看作一条数轴,青蛙初始在0上,这只青蛙可以向前跳也可以向后跳,但每次只能跳一格,每跳一格记作一步,从隧道进到隧道出算做一步。

输入描述:

第一行两个数m,n;表示黑色物品在数轴m点上,数轴上总共有n个隧道
接下来n行,每行a,b两个数,表示从a进会从b出

10 <= m,n <= 233

0<a,b<=m

输出描述:

一个数ans表示最小步数

 

示例1

输入

16 4
2 10
8 15
12 5
13 6

输出

7

说明

0-->1-->2-->10-->9-->8-->15-->16

解题:利用弗洛伊德来计算最短路

#include<bits/stdc++.h>
using namespace std;
const int MAXN=255;
int n,m;
int G[MAXN][MAXN];
void Floyd()
{
    for(int k=0;k<=n;++k)
        for(int i=0;i<=n;++i)
            for(int j=0;j<=n;++j)
                G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
}
int main()
{
    ios::sync_with_stdio(false);
    for(int i=0;i<MAXN;++i)
        for(int j=0;j<MAXN;++j)
            G[i][j]=abs(j-i);
    cin>>n>>m;
    int u,v;
    for(int i=0;i<m;++i)
    {
        cin>>u>>v;
        G[u][v]=1;
    }
    Floyd();
    cout<<G[0][n]<<endl;
    return 0;
}
 

F.三轮
 

题目描述

小k有一个三轮,它最多可以装105大小的东西
小k有n种商品,他要准备出摊了

每种商品体积为vi,都有105件

输出凑成1~m的体积的总方案数

输出可能会很大,请对大质数19260817取模

输入描述:

第一行两个整数n,m,
接下来n行,每行一个数代表vi

输出描述:

一个数ans表示总方案数

示例1

输入

2 8
1
3

输出

17

说明

从1~m体积的方案数分别为:
1
1
2
2
2
3
3
3

备注:

不要忘记取模!!!
n,m,vi <= 50000

解题:动态规划

#include<bits/stdc++.h>
using namespace std;
int n,m,a[50010],tmp;
const int mod=19260817;
int main()
{
    scanf("%d%d",&n,&m);
    a[0]=1;
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&tmp);
        for (int j=tmp;j<=m;j++)
        a[j]=(a[j]+a[j-tmp])%mod;
    }
    tmp=0;
    for (int i=1;i<=m;i++) 
        tmp=(tmp+a[i])%mod;
    printf("%d\n",tmp);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值