• 蓝桥杯2017真题 | java组


    1、迷宫 

    1. public class Main {
    2. static int count = 0;
    3. public static void main(String[] args) {
    4. char[][] ch = {
    5. { 'U', 'D', 'D', 'L', 'U', 'U', 'L', 'R', 'U', 'L' },
    6. { 'U', 'U', 'R', 'L', 'L', 'L', 'R', 'R', 'R', 'U' },
    7. { 'R', 'R', 'U', 'U', 'R', 'L', 'D', 'L', 'R', 'D' },
    8. { 'R', 'U', 'D', 'D', 'D', 'D', 'U', 'U', 'U', 'U' },
    9. { 'U', 'R', 'U', 'D', 'L', 'L', 'R', 'R', 'U', 'U' },
    10. { 'D', 'U', 'R', 'L', 'R', 'L', 'D', 'L', 'R', 'L' },
    11. { 'U', 'L', 'L', 'U', 'R', 'L', 'L', 'R', 'D', 'U' },
    12. { 'R', 'D', 'L', 'U', 'L', 'L', 'R', 'D', 'D', 'D' },
    13. { 'U', 'U', 'D', 'D', 'U', 'D', 'U', 'D', 'L', 'L' },
    14. { 'U', 'L', 'R', 'D', 'L', 'U', 'U', 'R', 'R', 'R' }
    15. };
    16. for (int i = 0; i < ch.length; i++) {
    17. for (int j = 0; j < ch[i].length; j++) {
    18. dfs(i, j, ch);
    19. }
    20. }
    21. System.out.println(count);
    22. }
    23. public static void dfs(int x, int y, char[][] ch) {
    24. int m = ch.length;
    25. int n = ch[0].length;
    26. if (x < 0 || y < 0 || x > m - 1 || y > n - 1) {
    27. count++;
    28. return;
    29. }
    30. char flag = ch[x][y];
    31. if (ch[x][y]=='p') {
    32. return;
    33. }
    34. ch[x][y] = 'p';
    35. if (flag == 'U') {
    36. dfs(x-1, y, ch);
    37. }
    38. if (flag =='L') {
    39. dfs(x, y-1, ch);
    40. }
    41. if (flag=='D') {
    42. dfs(x+1, y, ch);
    43. }
    44. if (flag =='R') {
    45. dfs(x, y+1, ch);
    46. }
    47. ch[x][y] = flag;
    48. }
    49. }

    总结:A组今年第一题就这么恶心,没做出来直接看题解,是道dfs,但是中间要检测是否走过,走过的直接退出,这里用了一个flag变量来标记,刚进来就记录原本的方向,然后赋值成P标识走过了,如果下次进来if成立为p就直接return,说明走过了,然后返回上一层把flag赋值回去(递归的时候每层的变量都是独立的 所以不存在下层的flag会吧上层覆盖,所以我们层都用自己的flag记录

    2、9数算式

    观察如下的算式:

    9213×85674=789314562

    左边的乘数和被乘数正好用到了 11 ~ 99 的所有数字,每个 11 次。 而乘积恰好也是用到了 11 ~ 99 的所有数字,并且每个 11 次。

    请你借助计算机的强大计算能力,找出满足如上要求的 99 数算式一共有多少个?

    注意:

    1. 总数目包含题目给出的那个示例。
    2. 乘数和被乘数交换后作为同一方案来看待。
    1. import java.util.Scanner;
    2. // 1:无需package
    3. // 2: 类名必须Main, 不可修改
    4. import java.util.HashSet;
    5. //import java.util.Scanner;
    6. import java.util.Set;
    7. public class Main {
    8. private static int[] a = {1,2,3,4,5,6,7,8,9};
    9. private static int ans;
    10. public static void main(String[] args) {
    11. // Scanner scan = new Scanner(System.in);
    12. // f(0);
    13. // System.out.println(ans);
    14. System.out.println(3250/2);
    15. // scan.close();
    16. }
    17. private static void f(int k) {
    18. if(k == 9) {
    19. for (int i = 1; i < 9; i++) {
    20. check(i);
    21. }
    22. }
    23. for (int i = k; i < a.length; i++) {
    24. int t = a[i];
    25. a[i] = a[k];
    26. a[k] = t;
    27. f(k+1);
    28. t = a[i];
    29. a[i] = a[k];
    30. a[k] = t;
    31. }
    32. }
    33. private static void check(int len) {
    34. int num1 =0;
    35. int num2 = 0;
    36. int t = 1;
    37. for (int i = len-1; i >= 0; i--) {
    38. num1 += a[i]*t;
    39. t*=10;
    40. }
    41. t = 1;
    42. for (int i = a.length-1; i >= len; i--) {
    43. num2 += a[i]*t;
    44. t*=10;
    45. }
    46. int num3 = num1*num2;
    47. String str = num3+"";
    48. if(str.length()!=9)return;
    49. Set set = new HashSet<>();
    50. for (int i = 0; i < str.length(); i++) {
    51. if (str.charAt(i)!='0') {
    52. set.add(str.charAt(i));
    53. }
    54. }
    55. if(set.size() == 9) {
    56. ans++;
    57. // System.out.printf("%d * %d == %d\n",num1,num2,num3);
    58. }
    59. }
    60. }

    总结:全排列,但是这个check比较难 第一个for是前面的数字,第二个是后面的数,然后相乘为9位数字而且不重复,就能ans++(放到set里面看有没有重复)

    3、字母组串

    由 A,B,C 这3个字母就可以组成许多串。 比如:"A","AB","ABC","ABA","AACBB" ....填空

    现在,小明正在思考一个问题: 如果每个字母的个数有限定,能组成多少个已知长度的串呢?

    他请好朋友来帮忙,很快得到了代码, 解决方案超级简单,然而最重要的部分却语焉不详。

    1. {
    2. // a个A,b个B,c个C 字母,能组成多少个不同的长度为n的串。
    3. static int f(int a, int b, int c, int n)
    4. {
    5. if(a<0 || b<0 || c<0) return 0;
    6. if(n==0) return 1;
    7. return ________________________________; //填空
    8. }
    9. public static void main(String[] args)
    10. {
    11. System.out.println(f(1,1,1,2));
    12. System.out.println(f(1,2,3,3));
    13. }
    14. }

    答案:f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1)

    总结:看到这种最后小于0的肯定是递归的递减,有3种情况,a减少,b减少,c减少然后把他们的数量相加就是各种情况的总和。

    4、最大公共子串

    最大公共子串长度问题就是: 求两个串的所有子串中能够匹配上的最大长度是多少。

    比如:"abcdkkk" 和 "baabcdadabc", 可以找到的最长的公共子串是"abcd",所以最大公共子串长度为 4。下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。

    请分析该解法的思路,并补全划线部分缺失的代码。填空

    1. import java.util.Scanner;
    2. public class Main
    3. {
    4. static int f(String s1, String s2)
    5. {
    6. char[] c1 = s1.toCharArray();
    7. char[] c2 = s2.toCharArray();
    8. int[][] a = new int[c1.length+1][c2.length+1];
    9. int max = 0;
    10. for(int i=1; i
    11. for(int j=1; j
    12. if(c1[i-1]==c2[j-1]) {
    13. a[i][j] = __________________________;
    14. if(a[i][j] > max) max = a[i][j];
    15. }
    16. }
    17. }
    18. return max;
    19. }
    20. public static void main(String[] args){
    21. int n = f("abcdkkk", "baabcdadabc");
    22. System.out.println(n);
    23. System.out.println(f("aaakkkabababa", "baabababcdadabc"));
    24. System.out.println(f("abccbaacbcca", "ccccbbbbbaaaa"));
    25. System.out.println(f("abcd", "xyz"));
    26. System.out.println(f("ab", "ab"));
    27. }
    28. }

    答案:a[i-1][j-1]+1

    总结:这题是动态规划,新的东西用到旧的,根据题大概可以理解到他是竖着遍历第一个字符串,横着遍历第二个,连续相等的话是斜着加的。从而可以推出当元素连续相等的时候,后面右下角的等于右上角元素加1。

    5、购物单

    小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。

    这不,大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。

    小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。

    现在小明很心烦,请你帮他计算一下,需要从取款机上取多少现金,才能搞定这次购物。

    取款机只能提供 100100 元面额的纸币。小明想尽可能少取些现金,够用就行了。 你的任务是计算出,小明最少需要取多少现金。

    以下是让人头疼的购物单,为了保护隐私,物品名称被隐藏了。

    1. **** 180.90 88
    2. **** 10.25 65
    3. **** 56.14 9
    4. **** 104.65 9
    5. **** 100.30 88
    6. **** 297.15 半价
    7. **** 26.75 65
    8. **** 130.62 半价
    9. **** 240.28 58
    10. **** 270.62 8
    11. **** 115.87 88
    12. **** 247.34 95
    13. **** 73.21 9
    14. **** 101.00 半价
    15. **** 79.54 半价
    16. **** 278.44 7
    17. **** 199.26 半价
    18. **** 12.97 9
    19. **** 166.30 78
    20. **** 125.50 58
    21. **** 84.98 9
    22. **** 113.35 68
    23. **** 166.57 半价
    24. **** 42.56 9
    25. **** 81.90 95
    26. **** 131.78 8
    27. **** 255.89 78
    28. **** 109.17 9
    29. **** 146.69 68
    30. **** 139.33 65
    31. **** 141.16 78
    32. **** 154.74 8
    33. **** 59.42 8
    34. **** 85.44 68
    35. **** 293.70 88
    36. **** 261.79 65
    37. **** 11.30 88
    38. **** 268.27 58
    39. **** 128.29 88
    40. **** 251.03 8
    41. **** 208.39 75
    42. **** 128.88 75
    43. **** 62.06 9
    44. **** 225.87 75
    45. **** 12.89 75
    46. **** 34.28 75
    47. **** 62.16 58
    48. **** 129.12 半价
    49. **** 218.37 半价
    50. **** 289.69 8

    需要说明的是,8888 折指的是按标价的 88%88 计算,而 88 折是按 80%80 计算,余者类推。 特别地,半价是按 50%50 计算。

    请输出小明要从取款机上提取的金额,单位是元。

    题解:这题考得就是excel的使用,我们直接算太慢了,最快的就是用excel表格。

    6、纸牌三角形

    A,2,3,4,5,6,7,8,9 共 99 张纸牌排成一个正三角形(AA 按 11 计算)。要求每个边的和相等。 下图就是一种排法。

    这样的排法可能会有很多。

    如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?

    请你计算并提交该数字。

    1. import java.util.Scanner;
    2. // 1:无需package
    3. // 2: 类名必须Main, 不可修改
    4. public class Main {
    5. static int ans =0;
    6. static int[] a = {1,2,3,4,5,6,7,8,9};
    7. public static void main(String[] args) {
    8. Scanner scan = new Scanner(System.in);
    9. //在此输入您的代码...
    10. fun(0);
    11. System.out.println(ans/6);
    12. scan.close();
    13. }
    14. static void fun(int start)
    15. {
    16. if(start==a.length){
    17. if(check()){
    18. ans++;
    19. }
    20. }
    21. for(int i =start;i
    22. int temp = a[start];
    23. a[start] = a[i];
    24. a[i] = temp;
    25. fun(start+1);
    26. temp = a[start];
    27. a[start] = a[i];
    28. a[i] = temp;
    29. }
    30. }
    31. static boolean check()
    32. {
    33. int x1 =a[0]+a[1]+a[2]+a[3];
    34. int x2 =a[3]+a[4]+a[5]+a[6];
    35. int x3 =a[6]+a[7]+a[8]+a[0];
    36. if(x1==x2&&x2==x3)
    37. {
    38. return true;
    39. }
    40. return false;
    41. }
    42. }

    总结:全排列。固定模板,但是有坑,他旋转和对称都算一种,那么对称要除2,旋转又有3种情况,所有ans一共要除以6

    7、取位数

    求1个整数的第k位数字有很多种方法。 以下的方法就是一种。填空

    1. import java.util.*;
    2. public class Main
    3. {
    4. static int len(int x){
    5. if(x<10) return 1;
    6. return len(x/10)+1;
    7. }
    8. // 取x的第k位数字
    9. static int f(int x, int k){
    10. if(len(x)-k==0) return x%10;
    11. return ______________________; //填空
    12. }
    13. public static void main(String[] args)
    14. {
    15. int x = 23513;
    16. //System.out.println(len(x));
    17. System.out.println(f(x,3));
    18. System.out.println(f(893275,2));
    19. }
    20. }

    答案:f(x/10,k)

    总结:当len(x)-k==0才return,大概率递归,递归要满足这个条件只能len减小或k变大,k是固定的,所以只能len(x)减小了,所以每次减小x/10,k不变

    8、分巧克力

    儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。

    小明一共有 NN 块巧克力,其中第 ii 块是 H_i \times WiHi​×Wi 的方格组成的长方形。为了公平起见,

    小明需要从这 NN 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足:

    1. 形状是正方形,边长是整数;

    2. 大小相同;

    例如一块 6x5 的巧克力可以切出 6 块 2x2 的巧克力或者 2 块 3x3 的巧克力。

    当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?

    输入描述

    第一行包含两个整数 N,KN,K (1 \leq N, K \leq 10^51≤N,K≤105)。

    以下 N 行每行包含两个整数 H_i,W_iHi​,Wi​ (1 \leq H_i, W_i \leq 10^51≤Hi​,Wi​≤105)。

    输入保证每位小朋友至少能获得一块 1x1 的巧克力。

    输出描述

    输出切出的正方形巧克力最大可能的边长。

    输入输出样例

    输入

    1. 2 10
    2. 6 5
    3. 5 6

    输出

    2
    1. public class Main {
    2. public static void main(String[] args) {
    3. Scanner scan = new Scanner(System.in);
    4. int n = scan.nextInt();
    5. int k = scan.nextInt();
    6. int[][] nums = new int[n][2];
    7. for (int i = 0; i < n; i++) {
    8. nums[i][0]= scan.nextInt();
    9. nums[i][1]= scan.nextInt();
    10. }
    11. int left = 1,right = 100000;
    12. while (left < right) {
    13. int mid = left + (right - left + 1) / 2;
    14. int count = 0;
    15. for (int i = 0; i < n; i++) {
    16. count+=(nums[i][0]/mid) * (nums[i][1]/mid);
    17. }
    18. if (count < k) {
    19. right = mid - 1;
    20. }else left = mid;
    21. }
    22. System.out.println(left);
    23. }
    24. }

    总结:暴力枚举题,枚举切的边长,当最后切出来的块数大于等于人数,就返回。我们可以优化为二分查找。

    9、杨辉三角

    杨辉三角也叫帕斯卡三角,在很多数量关系中可以看到,十分重要。

    1. 0行: 1
    2. 1行: 1 1
    3. 2行: 1 2 1
    4. 3行: 1 3 3 1
    5. 4行: 1 4 6 4 1
    6. ....

    两边的元素都是1, 中间的元素是左上角的元素与右上角的元素和。

    我们约定,行号,列号都从 0 计数。所以: 第 6 行的第 2 个元素是 15,第 3 个元素是 20。

    直观地看,需要开辟一个二维数组,其实一维数组也可以胜任。 如下程序就是用一维数组“腾挪”的解法。填空

    1. import java.util.Scanner;
    2. public class Main
    3. {
    4. // 杨辉三角形的第row行第col列
    5. static long f(int row, int col){
    6. if(row<2) return 1;
    7. if(col==0) return 1;
    8. if(col==row) return 1;
    9. long[] a = new long[row+1];
    10. a[0]=1;
    11. a[1]=1;
    12. int p = 2;
    13. while(p<=row){
    14. a[p] = 1;
    15. for( _________________ ) a[q] = a[q] + a[q-1];
    16. p++;
    17. }
    18. return a[col];
    19. }
    20. public static void main(String[] args){
    21. System.out.println(f(6,2));
    22. System.out.println(f(6,3));
    23. System.out.println(f(40,20));
    24. }
    25. }

    答案:int q=p-1;q>=1;q--

    总结:从上面可以看出来while循环是循环第几行,里面的for是为了遍历行内的元素,根据题目提示现在这个就是之前的a[q]+a[q-1],所以每次就是遍历这个q,我们要逆序遍历,为了不影响到下一次遍历

    10、Excel地址

    Excel 单元格的地址表示很有趣,它使用字母来表示列号。

    比如,

    A 表示第 1 列,

    B 表示第 2 列,

    Z 表示第 26 列,

    AA 表示第 27 列,

    AB 表示第 28 列,

    BA 表示第 53 列,

    当然 Excel 的最大列号是有限度的,所以转换起来不难。

    如果我们想把这种表示法一般化,可以把很大的数字转换为很长的字母序列呢?

    本题目即是要求对输入的数字, 输出其对应的 Excel 地址表示方式。

    输入描述

    输入一个整数 nn,其范围 [1,2147483647]。

    输出描述

    输出 nn 对应的 Excel 地址表示方式。

    输入输出样例

    示例

    输入

    26
    

    输出

    Z
    1. public class Main {
    2. public static void main(String[] args) {
    3. Scanner in = new Scanner(System.in);
    4. int n=in.nextInt();
    5. String str="";
    6. for(int s;n!=0;n/=26){
    7. if(n%26==0) {
    8. n-=26;
    9. s=26;
    10. }else {
    11. s=n%26;
    12. }
    13. str=(char)(s+64)+str;
    14. }
    15. System.out.print(str);
    16. in.close();
    17. }
    18. }

    总结:有点类似进制转换,循环每次都除26,除26前取余,然后记录余数,最后把他们字符串拼接起来,前面的余数在后面所以是str=(char)(s+64)+str; 其中如果除26==0就让s==26因为没有0这个对应的字母26就是z,然后n要减去26

    11、日期问题

    小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。

    更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

    比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03 月 02 日。

    给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

    输入描述

    一个日期,格式是 "AA/BB/CCAA/BB/CC" (0 \leq A, B, C \leq 90≤A,B,C≤9)。

    输出描述

    输出若干个不相同的日期,每个日期一行,格式是 "yyyy-MM-ddyyyy−MM−dd"。多个日期按从早到晚排列。

    输入输出样例

    示例

    输入

    02/03/04
    

    输出

    1. 2002-03-04
    2. 2004-02-03
    3. 2004-03-02
    1. package saunfati;
    2. import java.text.SimpleDateFormat;
    3. import java.util.Scanner;
    4. import java.util.TreeSet;
    5. public class 日期问题 {
    6. public static void main(String[] args) {
    7. Scanner scanner = new Scanner(System.in);
    8. String temp = scanner.next();
    9. String date[] = temp.split("/");
    10. String y = date[0];
    11. String m = date[1];
    12. String d = date[2];
    13. String a = (Integer.parseInt(y)<60?"20"+y:"19"+y)+"-"+m+"-"+d;
    14. String b = (Integer.parseInt(d)<60?"20"+d:"19"+d)+"-"+y+"-"+m;
    15. String c = (Integer.parseInt(d)<60?"20"+d:"19"+d)+"-"+m+"-"+y;
    16. TreeSet set = new TreeSet();
    17. if(f(a)) set.add(a);
    18. if(f(b)) set.add(b);
    19. if(f(c)) set.add(c);
    20. for(Object object:set) {
    21. System.out.println(object);
    22. }
    23. }
    24. static boolean f(String date) {
    25. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    26. format.setLenient(false);
    27. try {
    28. format.parse(date);
    29. }catch(Exception e) {
    30. return false;
    31. }
    32. return true;
    33. }
    34. }

    总结:本地可以用TreeSet来做到去重排序。而且可以用SimpleDateFormat的setLenient方法来判断日期是否有效的。

  • 相关阅读:
    vue3实现表格的分页以及确认消息弹窗
    服务器正文23:定时器设计与实现(8/7)
    StarRocks 自增ID实现分页优化
    Easyrecovery2022硬盘磁盘U盘免费数据恢复软件
    PTE 口语练习准备(一)
    郑州大学图书馆许少辉《乡村振兴战略下传统村落文化旅游设计》中文文献——2023学生开学季辉少许
    文件夹重命名:解决文件夹名称难题,批量将中文翻译成英文
    印刷行业APS解决方案
    正则表达式学习笔记
    基于QT实现的SSL协议的安全报文发送接收设计
  • 原文地址:https://blog.csdn.net/weixin_54232666/article/details/127772330