2019年javaB组蓝桥杯
第一题:组队
题目描述
作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容。
每位球员担任 1 号位至 5 号位时的评分如下表所示。请你计算首发阵容 1 号位至 5 号位的评分之和最大可能是多少?
答案:490
思路:直接将每个位置的分数最高的两个球员选出来,保证一个球员只在一个位置打球,多次对比,即得答案。
2.不同的子串:
一个字符串的非空子串是指字符串中长度至少为1 的连续的一段字符组成
的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共7 个。
注意在计算时,只算本质不同的串的个数。
请问,字符串0100110001010001 有多少个不同的非空子串?
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
答案:100
思路:将所有的字符串穷举一遍,放到hashset中,依靠hashset不能存放重复值,自动去重的特点。最后直接输出hashset的size即可
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Q2 {
public static void main(String[] args)
{
String a="0100110001010001";
Set <String>set = new HashSet<String>();//自动去除重复值
for(int i=0;i<a.length();i++) //穷举所有的字符串
{
for(int j=i;j<a.length();j++)
{
set.add(a.substring(i, j+1));//全部加入hashset,自动去重
}
}
System.out.println(set.size());
}
}
此题总结:https://blog.csdn.net/feiyanaffection/article/details/81394745?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
第三题:数列求值
题目描述
给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和。求 第 20190324 项的最后 4 位数字。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个 4 位整数(提示:答案的千位不为 0),在提交答案时只填写这个整数,填写 多余的内容将无法得分。
答案:4659
思路:开辟数组,将前四项放入数组中,按题意从第四项for循环求值,注意每次求完和要模10000,这样就只会计算后四位数字(如果不取模,数值会溢出,并且求出的值千位为0,不和题意)
import java.util.*;
public class Q3 {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int n=sc.nextInt();//输入查询第几项
int [] a=new int [n+1];
a[1]=1; a[2]=1; a[3]=1;
for(int i=4;i<a.length;i++)
{
a[i]=(a[i-1]+a[i-2]+a[i-3])%10000;
}
System.out.println(a[n]);
}
}
4.数的分解:
把2019 分解成3 个各不相同的正整数之和,并且要求每个正整数都不包
含数字2 和4,一共有多少种不同的分解方法?
注意交换3 个整数的顺序被视为同一种方法,例如1000+1001+18 和
1001+1000+18 被视为同一种。
答案:40785
思路:为提高程序执行速率,先创建一个标记数组a,将包含2和4的数字与不包含2、4的数字区分开。之后为避免重复解法分三个阶段测试三个数,最后将满足条件的累计解法sum输出。
public class T4 {
static int []a=new int[2020];
public static void main(String[] args) {
//将1到2019的数排列出来
//标记数组
for(int i=1;i<2020;i++) {
//给初始化状态1
a[i]=1;
char []b=String.valueOf(i).toCharArray();//将从1到2019的数字转成字符数组
for(int j=0;j<b.length;j++) {
if(b[j]=='2'||b[j]=='4') {
a[i]=0;//标记为不能使用
}
}
}
int sum=0;
for(int x=1;x<2019/3+1;x++) {
if(check(x)){
for(int y=x+1;y<2019;y++) {
if(check(y)) {
for(int z=y+1;z<2019;z++) {
if(x+ y + z >2019) {
break;
}
if(check(z)) {
if(x+y+z==2019) {
sum++;
}
}
}
}
}
}
}
System.out.println(sum);
}
private static boolean check(int x) {
// TODO Auto-generated method stub
if(a[x]==1) {//查看该数是否能使用
return true;
}
else {
return false;
}
}
}
6.特别数的和:
小明对数位中含有2、0、1、9 的数字很感兴趣(不包括前导0),在1 到
40 中这样的数包括1、2、9、10 至32、39 和40,共28 个,他们的和是574。
请问,在1 到n 中,所有这样的数的和是多少?
输入:
输入一行包含一个整数n。
输出:
输出一行,包含一个整数,表示满足条件的数的和。
【样例输入】
40
【样例输出】
574
**思路:**遍历1到n,利用String的valueOf()方法,将数字转成字符串,然后再利用toCharArray()方法将其转成字符数组,循环字符数组判断是否含有2、0、1、9,满足条件的累计,最后输出。
代码如下:
import java.util.*;
public class Q6 {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int n=sc.nextInt();
int sum=0;
for(int i=1;i<=n;i++)
{
char []a=String.valueOf(i).toCharArray();//数字转成字符串然后再转成字符数组
for(int j=0;j<a.length;j++)
{
if(a[j]=='2'||a[j]=='0'||a[j]=='1'||a[j]=='9') {
sum+=i;
break;
}
}
}
System.out.println(sum);
}
}
7.外卖店优先级:
“饱了么”外卖系统中维护着N 家外卖店,编号1 - N。每家外卖店都有
一个优先级,初始时(0 时刻) 优先级都为0。
每经过1 个时间单位,如果外卖店没有订单,则优先级会减少1,最低减
到0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加2。
如果某家外卖店某时刻优先级大于5,则会被系统加入优先缓存中;如果
优先级小于等于3,则会被清除出优先缓存。
给定T 时刻以内的M 条订单信息,请你计算T 时刻时有多少外卖店在优
先缓存中。
【输入格式】
第一行包含3 个整数N、M 和T。
以下M 行每行包含两个整数ts 和id,表示ts 时刻编号id 的外卖店收到
一个订单。
【输出格式】
输出一个整数代表答案。
【样例输入】
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
【样例输出】
1
【样例解释】
6 时刻时,1 号店优先级降到3,被移除出优先缓存;2 号店优先级升到6,
加入优先缓存。所以是有1 家店(2 号) 在优先缓存中。
废话不多说,上代码
import java.util.*;
public class M7 {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int N=sc.nextInt();//外卖店的个数
int M=sc.nextInt();//订单数量
int T=sc.nextInt();//进行的时刻
int [][] a=new int[M][2];
for(int i=0;i<M;i++)
{
for(int j=0;j<2;j++)
{
a[i][j]=sc.nextInt();
}
}
int []score=new int [N];
int []sign =new int [N];
Set<Integer> set =new HashSet<Integer>();//缓存
for(int i=1;i<=T;i++)
{
for(int j=0;j<M;j++)
{
if(a[j][0]==i)//订单时刻等于此时时刻
{
score[a[j][1]-1]+=2;//分数加2
if(score[a[j][1]-1]>5) {
set.add(a[j][1]-1);//对应的商店编号存入缓存
}
sign[a[j][1]-1]=1;//标记次趟已有过一次订单了
}
}
for(int m=0;m<N;m++)
{
if(sign[m]==0&& score[m]>0)//本趟中没有订单的外卖店
{
score[m]--;
}
if(score[m]<=3) {
set.remove(m);
}
}
sign =new int [N];//一趟完成后标记归零
}
System.out.println(set.size());
}
}
第八题:人物相关性分析
题目描述
小明正在分析一本小说中的人物相关性。他想知道在小说中 Alice 和 Bob 有多少次同时出现。
更准确的说,小明定义 Alice 和 Bob“同时出现”的意思是:在小说文本 中 Alice 和 Bob 之间不超过 K 个字符。
例如以下文本:
ThisisastoryaboutAliceandBob.AlicewantstosendaprivatemessagetoBob.
假设 K = 20,则 Alice 和 Bob 同时出现了 2 次,分别是”Alice and Bob” 和”Bob. Alice”。前者 Alice 和 Bob 之间有 5 个字符,后者有 2 个字符。
注意:
- Alice 和 Bob 是大小写敏感的,alice 或 bob 等并不计算在内。
- Alice 和 Bob 应为单独的单词,前后可以有标点符号和空格,但是不能 有字母。例如 Bobbi 並不算出现了 Bob。
【输入格式】
第一行包含一个整数 K。
第二行包含一行字符串,只包含大小写字母、标点符号和空格。长度不超 过 1000000。
【输出格式】
输出一个整数,表示 Alice 和 Bob 同时出现的次数。
【样例输入】
20
ThisisastoryaboutAliceandBob.AlicewantstosendaprivatemessagetoBob.
【样例输出】
2
思路:利用split方法将英文句子按空格和英文句号分割成字符数组,
分两种情况:
1.从Alice去查找Bob,记录其距离kk,不超过规定的K则次数+1。
2.从Bob去查找Alice,记录其距离kk,不超过规定的K则次数+1。
import java.util.*;
public class T8 {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int K=sc.nextInt();//最大间隔距离
String s=sc.next();//输入该串
String[]word=s.split("\\s+|\\.");//按空格和英文句号切分句子
int[] wordlength =new int[word.length];//存储各个单词的长度
for(int i=0;i<word.length;i++)
{
wordlength[i]=word[i].length();
}
//Alice距离Bob
int sum=0;//符合条件的总数
for(int i=0;i<word.length;i++) {
if(word[i].equals("Alice")) {
//从后面的单词找
for(int j=i+1;j<word.length;j++) {
int kk=1;//空格
if(word[j].equals("Bob")) {
for(int m=i+1;m<j;m++) {
kk+=wordlength[m]+1;//每个单词长度加上一个空格
}
if(kk<=K) {
sum++;
}
}
}
}
}
for(int i=0;i<word.length;i++) {
if(word[i].equals("Bob")) {
for(int j=i+1;j<word.length;j++) {
int kk=1;
if(word[j].equals("Alice")) {
for(int m=i+1;m<j;m++) {
kk+=wordlength[m]+1;
}
if(kk<=K) {
sum++;
}
}
}
}
}
System.out.println(sum);
}
}
第九题:后缀表达式
题目描述
给定 N 个加号、M 个减号以及 N + M + 1 个整数 A1,A2,··· ,AN+M+1,小 明想知道在所有由这 N 个加号、M 个减号以及 N + M +1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个?
请你输出这个最大的结果。
例如使用1 2 3 + -,则 “2 3 + 1 -” 这个后缀表达式结果是 4,是最大的。
【输入格式】
第一行包含两个整数 N 和 M。 第二行包含 N + M + 1 个整数 A1,A2,··· ,AN+M+1。
【输出格式】
输出一个整数,代表答案。
【样例输入】
1 1
1 2 3
【样例输出】
4
思路:要想表达式结果最大,尽量让大的数进行相加,减去那些较小的数。
这道题先让输入的所有数进行排序,倒序,加上较大的数,用完加号。最后将剩下的较小数减去,用完减号即可
import java.util.*;
public class T9 {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int N=sc.nextInt();//加号个数
int M=sc.nextInt();//减号个数
int[]a =new int[N+M+1];//有n+m+1个数字
for(int i=0;i<a.length;i++)
{
a[i]=sc.nextInt();
}
Arrays.sort(a);//对输入的数进行排序
int sum=0;
int x=0;//加号摆放次数
for(int i=a.length-1;i>=0;i--)//对数组进行倒序操作
{
if(x<N+1) {
sum=sum+a[i];
}
x++;
if(x==N+1) {
continue;
}
if(x>N+1) {
sum=sum-a[i];
}
}
System.out.println(sum);
}
}