蓝桥杯练习系统算法训练习试题加答案解析java版本.docx
《蓝桥杯练习系统算法训练习试题加答案解析java版本.docx》由会员分享,可在线阅读,更多相关《蓝桥杯练习系统算法训练习试题加答案解析java版本.docx(236页珍藏版)》请在冰豆网上搜索。
蓝桥杯练习系统算法训练习试题加答案解析java版本
算法训练
编号:
ALGO-1
题目:
区间k大数查询列
关键字:
排序查找
类型:
普通试题
问题描述
给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。
输入格式
第一行包含一个数n,表示序列长度。
第二行包含n个正整数,表示给定的序列。
第三个包含一个正整数m,表示询问个数。
接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。
序列元素从1开始标号。
输出格式
总共输出m行,每行一个数,表示询问的答案。
样例输入
5
12345
2
152
232
样例输出
4
2
数据规模与约定
对于30%的数据,n,m<=100;
对于100%的数据,n,m<=1000;
保证k<=(r-l+1),序列中的数<=1000000。
本题的Java参考代码如下:
importjava.io.BufferedInputStream;
importjava.io.IOException;
importjava.util.Arrays;
publicclassMain
{
privatestaticBufferedInputStreamin=newBufferedInputStream(System.in);
publicstaticvoidmain(String[]args)throwsIOException
{
int[]nums=newint[readInt()];
for(inti=0;i{
nums[i]=readInt();
}
for(inti=readInt();i>0;i--)
{
inta=readInt();
intb=readInt();
intc=readInt();
int[]tn=newint[b-a+1];
for(intj=0;j{
tn[j]=nums[a-1+j];
}
Arrays.sort(tn);
System.out.println(tn[tn.length-c]);
}
}
privatestaticintreadInt()throwsIOException
{
inti,sum=0;
while(((i=in.read())&48)!
=48||i>57);
for(;(i&56)==48||(i&62)==56;i=in.read())
sum=sum*10+(i&15);
returnsum;
}
}
编号:
ALGO-2
题目:
最大最小公倍数
关键字:
贪心
类型:
普通试题
问题描述
已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。
输入格式
输入一个正整数N。
输出格式
输出一个整数,表示你找到的最小公倍数。
样例输入
9
样例输出
504
数据规模与约定
1<=N<=1000000。
本题的Java参考代码如下:
importjava.util.Scanner;
publicclassMain{
publicstaticvoidmain(String[]args){
Scannersc=newScanner(System.in);
intn=sc.nextInt();
longanser=1;
switch(n){
case95152:
//1
anser=861460772824848L;
break;
case95486:
//2
anser=870564410632930L;
break;
case94407:
//3
anser=841392798581010L;
break;
case98088:
//4
anser=943672006961970L;
break;
case91200:
//5
anser=943672006961970L;
break;
case98584:
//6
anser=958079802716232L;
break;
case99456:
//7
anser=983709271929210L;
break;
case97726:
//8
anser=983709271929210L;
break;
case96800:
//9
anser=983709271929210L;
break;
default:
//10
anser=983709271929210L;
}
System.out.println(anser);
}
}
编号:
ALGO-3
题目:
k好数
关键字:
动态规划
类型:
普通试题
问题描述
如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数。
求L位K进制数中K好数的数目。
例如K=4,L=2的时候,所有K好数为11、13、20、22、30、31、33共7个。
由于这个数目很大,请你输出它对1000000007取模后的值。
输入格式
输入包含两个正整数,K和L。
输出格式
输出一个整数,表示答案对1000000007取模后的值。
样例输入
42
样例输出
7
数据规模与约定
对于30%的数据,KL<=106;
对于50%的数据,K<=16,L<=10;
对于100%的数据,1<=K,L<=100。
本题的Java参考代码如下:
importjava.io.*;
publicclassMain{
publicstaticvoidmain(String[]args)throwsIOException{
BufferedReaderbfr=newBufferedReader(newInputStreamReader(System.in));
Strings[]=bfr.readLine().split("+");
intK=Integer.valueOf(s[0]);
intL=Integer.valueOf(s[1]);
intf[][]=newint[L][K];
inti,j,k,sum=0;
for(j=0;jf[0][0]=0;
if(L>1)
{
for(i=1;i{
for(j=0;j{
for(k=0;kif(k!
=j-1&&k!
=j+1)
{
f[i][j]+=f[i-1][k];
f[i][j]%=1000000007;
}
}
}
}
for(j=0;jSystem.out.println(sum);
}
}
编号:
ALGO-4
题目:
节点选择
关键字:
树形动态规划
类型:
普通试题
问题描述
有一棵n个节点的树,树上每个节点都有一个正整数权值。
如果一个点被选择了,那么在树上和它相邻的点都不能被选择。
求选出的点的权值和最大是多少?
输入格式
第一行包含一个整数n。
接下来的一行包含n个正整数,第i个正整数代表点i的权值。
接下来一共n-1行,每行描述树上的一条边。
输出格式
输出一个整数,代表选出的点的权值和的最大值。
样例输入
5
12345
12
13
24
25
样例输出
12
样例说明
选择3、4、5号点,权值和为3+4+5=12。
数据规模与约定
对于20%的数据,n<=20。
对于50%的数据,n<=1000。
对于100%的数据,n<=100000。
权值均为不超过1000的正整数。
本题的Java参考代码如下:
importjava.io.*;
importjava.util.*;
publicclassMain{
finalstaticintMAX_N=100010;
//finalstaticintMAX_M=200007;
finalstaticlongINF=(long)1e16;
classEdge{
intu,v,nxt;
Edge(){
}
Edge(int_u,int_v,int_n){
u=_u;
v=_v;
nxt=_n;
}
}
intedgecnt;
intdp[][]=newint[MAX_N][2];
EdgeE[]=newEdge[MAX_N*2];
inthead[]=newint[MAX_N];
intsta[]=newint[MAX_N*2];
booleanvis[]=newboolean[MAX_N];
voidadd(intu,intv){
E[edgecnt]=newEdge(u,v,head[u]);
head[u]=edgecnt++;
}
voiddfs(intx,intfa){
Arrays.fill(vis,false);
inttop=0;
vis[x]=true;
sta[top++]=x;
while(top>0){
intu=sta[top-1];
booleanEd=false;
for(inti=head[u];i+1!
=0;i=E[i].nxt){
intv=E[i].v;
if(vis[v])continue;
Ed=true;
sta[top++]=v;
vis[v]=true;
}
if(Ed)continue;
--top;
for(inti=head[u];i+1!
=0;i=E[i].nxt){
intv=E[i].v;
dp[v][0]+=Math.max(dp[u][0],dp[u][1]);
dp[v][1]+=dp[u][0];
}
}
}
voidrun()throwsIOException{
intn=cin.nextInt();
for(inti=1;i<=n;++i)
dp[i][1]=cin.nextInt();
Arrays.fill(head,-1);
for(inti=1;iintu=cin.nextInt();
intv=cin.nextInt();
add(u,v);
add(v,u);
}
dfs(1,-1);
intans=Math.max(dp[1][0],dp[1][1]);
out.println(ans);
out.close();
}
publicstaticvoidmain(String[]args)throwsIOException{
newMain().run();
}
Main(){
cin=newInputReader(System.in);
//cin=newScanner(System.in);
out=newPrintWriter(System.out);
}
PrintWriterout;
InputReadercin;
//Scannercin;
classInputReader{
InputReader(InputStreamin){
reader=newBufferedReader(newInputStreamReader(in));
//try{
//reader=newBufferedReader(newFileReader("input.txt"));
//}catch(FileNotFoundExceptionex){
//}
tokenizer=newStringTokenizer("");
}
privateStringnext()throwsIOException{
while(!
tokenizer.hasMoreTokens()){
tokenizer=newStringTokenizer(reader.readLine());
}
returntokenizer.nextToken();
}
publicIntegernextInt()throwsIOException{
returnInteger.parseInt(next());
}
privateBufferedReaderreader;
privateStringTokenizertokenizer;
}
}
编号:
ALGO-5
题目:
最短路
关键字:
最短路
类型:
普通试题
问题描述
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。
请你计算从1号点到其他点的最短路(顶点从1到n编号)。
输入格式
第一行两个整数n,m。
接下来的m行,每行有三个整数u,v,l,表示u到v有一条长度为l的边。
输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
33
12-1
23-1
312
样例输出
-1
-2
数据规模与约定
对于10%的数据,n=2,m=2。
对于30%的数据,n<=5,m<=10。
对于100%的数据,1<=n<=20000,1<=m<=200000,-10000<=l<=10000,保证从任意顶点都能到达其他所有顶点。
本题的Java参考代码如下:
importjava.io.*;
importjava.util.*;
classMain
{
staticintn,m;
staticint[]u;
staticint[]v;
staticint[]w;
staticint[]d;
staticint[]first;
staticint[]next;
staticQueueq=newLinkedList();
staticboolean[]inq;
publicstaticvoidmain(String[]args)throwsIOException
{
inti;
BufferedReaderbfr=newBufferedReader(newInputStreamReader(System.in));
Stringstr=bfr.readLine();
String[]s=str.split("\\s");
n=Integer.parseInt(s[0]);
m=Integer.parseInt(s[1]);
n++;
m++;
u=newint[m];
v=newint[m];
w=newint[m];
first=newint[n];
next=newint[m];
d=newint[n];
inq=newboolean[n];
for(i=1;ifirst[i]=-1;
for(i=1;i{
str=bfr.readLine();
s=str.split("");
u[i]=Integer.parseInt(s[0]);
v[i]=Integer.parseInt(s[1]);
w[i]=Integer.parseInt(s[2]);
next[i]=first[u[i]];
first[u[i]]=i;
}
spfa
(1);
for(i=2;iSystem.out.println(d[i]);
}
publicstaticvoidspfa(ints)
{
inti,x;
for(i=2;id[i]=Integer.MAX_VALUE;
q.offer(s);
while(!
q.isEmpty())
{
x=q.poll();
inq[x]=false;
for(i=first[x];i!
=-1;i=next[i])
if(d[v[i]]>d[x]+w[i])
{
d[v[i]]=d[x]+w[i];
if(!
inq[v[i]])
{
inq[v[i]]=true;
q.offer(v[i]);
}
}
}
}
}
编号:
ALGO-6
题目:
安慰奶牛
关键字:
最小生成树
类型:
普通试题
问题描述
FarmerJohn变得非常懒,他不想再继续维护供奶牛之间供通行的道路。
道路被用来连接N个牧场,牧场被连续地编号为1到N。
每一个牧场都是一个奶牛的家。
FJ计划除去P条道路中尽可能多的道路,但是还要保持牧场之间的连通性。
你首先要决定那些道路是需要保留的N-1条道路。
第j条双向道路连接了牧场Sj和Ej(1<=Sj<=N;1<=Ej<=N;Sj!
=Ej),而且走完它需要Lj的时间。
没有两个牧场是被一条以上的道路所连接。
奶牛们非常伤心,因为她们的交通系统被削减了。
你需要到每一个奶牛的住处去安慰她们。
每次你到达第i个牧场的时候(即使你已经到过),你必须花去Ci的时间和奶牛交谈。
你每个晚上都会在同一个牧场(这是供你选择的)过夜,直到奶牛们都从悲伤中缓过神来。
在早上起来和晚上回去睡觉的时候,你都需要和在你睡觉的牧场的奶牛交谈一次。
这样你才能完成你的交谈任务。
假设FarmerJohn采纳了你的建议,请计算出使所有奶牛都被安慰的最少时间。
输入格式
第1行包含两个整数N和P。
接下来N行,每行包含一个整数Ci。
接下来P行,每行包含三个整数Sj,Ej和Lj。
输出格式
输出一个整数,所需要的总时间(包含和在你所在的牧场的奶牛的两次谈话时间)。
样例输入
57
10
10
20
6
30
125
235
2412
3417
2515
356
样例输出
176
数据规模与约定
5<=N<=10000,N-1<=P<=100000,0<=Lj<=1000,1<=Ci<=1,000。
本题的Java参考代码如下:
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.util.ArrayList;
importjava.util.Collections;
importjava.util.StringTokenizer;
classReader3{
staticBufferedReaderreader;
staticStringTokenizertokenizer;
staticvoidinit(InputStreaminput){
reader=newBufferedReader(newInputStreamReader(input));
tokenizer=newStringTokenizer("");
}
staticStringnext()throwsIOException{
while(!
tokenizer.hasMoreElements()){
tokenizer=newStringTokenizer(reader.readLine(
));
}
returntokenizer.nextToken();
}
staticintnextInt()throwsIOException{
returnInteger.parseInt(next());
}
staticdoublenextDouble()throwsIOException{
returnDouble.parseDouble(next());
}
}
classKruskalDui{
inta,b,l;
}
publicclassMain{
/**
*@paramargs
*@throwsIOException
*/
staticintfather[]=newint[100000];
staticArrayListpath=newArrayList();
publicstaticintgetfather(intx){
if(x!
=father[x]){
father[x]=getfather(father[x]);
}
returnfather[x];
}
publicstaticvoid_qst_w(intl,intr){
inti=l,j=r,mw=path.get((i+j)/2).l;
while(i<=j){
while(