【省赛B组】2019年第十届蓝桥杯(解法通用)

001 组队(暴力)

一、题目描述

作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容。 每位球员担任 1 号位至 5 号位时的评分如下表所示。

请你计算首发阵容 1 号位至 5 号位的评分之和最大可能是多少?

二、题解(枚举)

这题可以手算,也可以通过程序解决,这里给出代码

总体思路:

  • 开数组new int[5][20]初始化数组存储表格数据
  • 双层循环枚举每一个评分,前提是5个位置都不相同
  • 最后就是比较本次的maxScore与上一次的maxScore
import java.util.Scanner;
/**
 * @Author: Hoji
 * @Description:
 * @Date: 11/18/2019 9:46 PM
 */
public class Main{
  public static void main(String[] args) {
    int[][] score = new int[20][5];
    int maxScores = 0;
    calc(score, maxScores);
    System.out.println(maxScores);
  }
  private static int calc(int[][] score, int maxScores) {
    Scanner s = new Scanner(System.in);
    for (int i = 0; i < 5; i++)
    for (int j = 0; j < 20; j++)
    score[i][j]= s.nextInt();

    for (int i = 0; i < 20; i++)
    for (int j = 0; j < 20; j++)
    for (int k = 0; k < 20; k++)
    for (int l = 0; l < 20; l++)
    for (int m = 0; m < 20; m++)
    //须知:比较符号的传递性
    if((i!=j && i!=k && i!=l && i!=m) &&
       (j!=k && j!=l && j!=m) &&
       (k!=l && k!=m) &&
       (l!=m))
    maxScores = Math.max(score[i][0] + score[j][1] + 
    				     score[k][2] + score[l][3] + score[m][4], maxScores);
    return maxScores;
  }
}

002 不同子串(暴力)

一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成
的串。例如,字符串aaab有非空子串a, b, aa, ab, aaa, aab, aaab,一共 7 个。注意在计算时,只算本质不同的串的个数。

请问,字符串 0100110001010001 有多少个不同的非空子串?

题解

/**
 * @Author: Hoji
 * @Description:
 * @Date: 11/18/2019 10:17 PM
 */
import java.util.HashSet;
public class Main{
  public static void main(String[] args) {
    System.out.println(calc("0100110001010001"));
  }
  private static int calc(String s) {
    int len = s.length();
    HashSet<String> set = new HashSet<>();
    for (int i = 0; i < len; i++)   
    for (int j = 0; i < len; j++)
    set.add(s.substring(i,j+1));
    return set.size();
  }
}

002 年号子串(C语言)

小明用字母A 对应数字1,B 对应2,以此类推,用Z 对应26。对于27
以上的数字,小明用两位或更长位的字符串来对应,例如AA 对应27,AB 对
应28,AZ 对应52,LQ 对应329。请问2019 对应的字符串是什么?

这题主要考察进制的转换,这题相当于 26 进制。可以对比十进制,对10取模(取余)得到数的个位数,对 %26 得到 2019 对应 26 进制的最后一位字符的26进制

/**
 * @Author: Hoji(PAN先森)
 * @Description:
 * @Date: 11/22/2019 12:20 AM
 * @个人博客:https://www.hoji.site
 */
public class Main{
  public static void main(String[] args) {
    char[] letters = new char[27];
    letters[0]='A';
    for (int i = 1; i < 27; ++i)
    letters[i] = (char)(letters[i-1]+1);

    StringBuilder ans=new StringBuilder("");
    int year = 2019;
    int t;
    while(year>0) {
      t=year%26;
      ans.append(letters[t]);
      year /= 26;
    }
    System.out.println(ans.reverse());
  }
}

递归求解:先递归求出2019的对应26进制的第一位数字,比如十进制27对应的26进制的就是11(26^1 + 26^0),那么十进制的27对应的年号子串 == AA.

/**
 * @Author: Hoji(PAN先森)
 * @Description:
 * @Date: 11/22/2019 12:20 AM
 * @个人博客:https://www.hoji.site
 */
public class Main{
  private static void solve(int i) {
    if(i <= 0) return;
    solve(i/26);
    System.out.println((char)(i%26 + 64));
  }
  public static void main(String[] args) {
	solve(2019);
  }
}

答案:BYQ


003 数列求值(数学)

一、题目描述

给定数列 1, 1, 1, 3, 5, 9, 17, …,从第4项开始,每项都是前3项的和。求第20190324 项的最后4 位数字。

二、题解

问题本质:问题的本质与求斐波拉契数列的问题相同

隐含条件:求最后4位数字的意思其实是:第20190324项的数值肯定不止4位数,故不管前面的数的位数的多少,我们只把数的最后四位取出!

/**
 * @Author: Hoji
 * @Description:
 * @Date: 11/18/2019 10:17 PM
 * @MyBlog:https://www.hoji.site ,一个富集创作与分享的乐园
 */
 public class Main {
	public static void main(String[] args) {
	int t0=5, t1=9, t2=17;
	int t = 0;
	for(int i=7; i<20190321; i++) {
	  t = (t0 + t1 + t2) % 10000;
	  t0 = t1;		//指针向前移动
	  t1 = t2;
	  t2 = t;
	}
	System.out.println(t2);	//4694
  }
}

004 数的分解(暴力)

一、题目

把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包 含数字 2 和 4,一共有多少种不同的分解方法? 注意交换 3 个整数的顺序被视为同一种方法,例如1000+1001+181001+1000+18被视为同一种。

二、题解

题目信息

  • 三个不同的正整数
  • 三个数都不包含24
  • 顺序相同,看做同一种

功能抽取:

  • 三个不同的正整数:用三个for,每一个循环的初始值都是上有一个循环变量的值+1,以确保数的不一致
  • 不包含24,见check()函数
  • 与(1)是一个意思
/**
 * @Author: Hoji
 * @Date: 11/14/2019 8:36 PM
 * @MyBlog:https://www.hoji.site ,一个富集创作与分享的乐园
 */
import java.util.HashSet;
import java.util.Set;
public class Main{
  public static boolean check(int n) {
    int g; 
    while (n > 0) {
   	  g=t%10;
      if(g == 2 || g == 4) return false;
      n/=10;
    }
    return true;
  }
  public static void main(String[] args) {
    int ans=0;
    for (int i = 1; i < 2019; i++)
	for (int j = i+1; j < 2019; j++)
	for (int k = j+1; k < 2019; k++)
	if(check(i) && check(j) && check(k))
	if(i+j+k==2019) ++ans;
	System.out.println(ans);
  }
}

005 迷宫

一、题目描述

下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方。

010000 
000100 
001001 
110000

迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这个它的上、下、左、右四个方向之一.

对于上面的迷宫,从入口开始,可以按 DRRURRDDDR 的顺序通过迷宫, 一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。 对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。

二、题解

大致思路

  • 构造迷宫数组 -> maze.charAt(50 * i + j) - ‘0’; 表示每50次j循环换一行,减去字符 ‘0’,相当于减去 ‘0’ 的 ASCII 码,最后变成数字。
  • 然后就是构造 BFS 思路咯,BFS 一般都是利用 Queue 的 FIFO 性质,这样就可以从一个扩展到一个面(一个 Node 出队时,将其D、L、R、U四个方向的结点入队,不断重复该过程,知道 queue 为空)
/**
 * @Author: Hoji(PAN先森)
 * @Description:
 * @Date: 11/19/2019 10:17 PM
 * @个人博客:https://www.hoji.site
 */
import java.util.LinkedList;
import java.util.Queue;
public class Main {
  public static void main(String[] args) {
    int[][] data = new int[30][50];
    for (int i = 0; i < 30; i++)
    for (int j = 0; j < 50; j++)
      data[i][j] = maze.charAt(50 * i + j) - '0';
    //字典序:D(x+1,y)、L(x, y-1)、R(x, y+1)、U(x+1, y)
    int[][] dir = {
            {1, 0},    //(0,0) (0,1) D
            {0, -1},   //(1,0) (1,1) L
            {0, 1},    //(2,0) (2,1) R
            {-1,0}};   //(3,0) (3,1) U
    boolean[][] isVisited = new boolean[30][50];
    String[] direction = { "D", "L", "R","U"};
    LinkedList<Node1> queue = new LinkedList<>();
    int tx=0, ty=0;
    isVisited[0][0]=true;
    String s = "";
    queue.offer(new Node(0,0,0,""));
    while(!queue.isEmpty()) {
      Node currNode = queue.poll();
      if(currNode .x == 29 && currNode.y == 49)
        System.out.println((currNode.ans)); //186
      for (int i = 0; i < 4; i++) {
        tx=currNode .x + dir[i][0];
        ty=currNode .y + dir[i][1];
        if (tx<0 || tx>=30 || ty<0 || ty>=50 || isVisited[tx][ty] || data[tx][ty]==1) {
          continue;
        }
        s=direction[i];
        isVisited[tx][ty]=true;
        queue.offer(new Node(tx, ty, currNode .step+1, currNode .ans+s));
      }
    }
  }
  private static String maze =
      "01010101001011001001010110010110100100001000101010"
    + "00001000100000101010010000100000001001100110100101"
    + "01111011010010001000001101001011100011000000010000"
    + "01000000001010100011010000101000001010101011001011"
    + "00011111000000101000010010100010100000101100000000"
    + "11001000110101000010101100011010011010101011110111"
    + "00011011010101001001001010000001000101001110000000"
    + "10100000101000100110101010111110011000010000111010"
    + "00111000001010100001100010000001000101001100001001"
    + "11000110100001110010001001010101010101010001101000"
    + "00010000100100000101001010101110100010101010000101"
    + "11100100101001001000010000010101010100100100010100"
    + "00000010000000101011001111010001100000101010100011"
    + "10101010011100001000011000010110011110110100001000"
    + "10101010100001101010100101000010100000111011101001"
    + "10000000101100010000101100101101001011100000000100"
    + "10101001000000010100100001000100000100011110101001"
    + "00101001010101101001010100011010101101110000110101"
    + "11001010000100001100000010100101000001000111000010"
    + "00001000110000110101101000000100101001001000011101"
    + "10100101000101000000001110110010110101101010100001"
    + "00101000010000110101010000100010001001000100010101"
    + "10100001000110010001000010101001010101011111010010"
    + "00000100101000000110010100101001000001000000000010"
    + "11010000001001110111001001000011101001011011101000"
    + "00000110100010001000100000001000011101000000110011"
    + "10101000101000100010001111100010101001010000001000"
    + "10000010100101001010110000000100101010001011101000"
    + "00111100001000010000000110111000000001000000001011"
    + "10000001100111010111010001000110111010101101111000";
}
class Node {
  int x,y;
  @Override
  public String toString() {
    return "Node{" +
            "ans='" + ans + '\'' +
            '}';
  }
  int step;
  String ans;
  Node(int x1, int y1, int step1, String ans1) {
    x=x1; y=y1;
    step = step1;
    ans = ans1;
  }
}

006 特别数的和

小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。 请问,在 1 到 n 中,所有这样的数的和是多少?

【样例输入】 40
【样例输出】 574

二、题解(暴力枚举)

这题算是比较简单的一题了,直接枚举[1~n]中的每一位数字,如果数字中含有2 / 0 / 1 / 9其中之一,那么sum+=i

/**
 * @Author: Hoji
 * @Description:
 * @Date: 11/19/2019 10:17 AM
 */
import java.util.Scanner;
public class B6_特别数的和 {
  public static void main(String[] args) {
    int n;
    Scanner s = new Scanner(System.in);
    try {
      n = s.nextInt();
      int sum=0;
      String sn;
      for (int i = 1; i <= n; i++) {
        sn=i+"";
        if(sn.indexOf("0") > -1||sn.indexOf("1") > -1 ||
           sn.indexOf("2") > -1||sn.indexOf("9") > -1)
        sum+=i;
      }
      System.out.println(sum);
    }
    catch (Exception e) {
      s.close();
    }
  }
}

总结

题号考察点
001 组队枚举
002 不同子串枚举,HashSet
003 年号子串进制转换
004 数的分解枚举
005 迷宫dfs
006 特别数的和枚举
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值