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;
}