蓝桥杯备战笔记分享(java)

蓝桥杯(10道题)

jdk 8

main函数

1.填空题(只需要给答案)

2道,每题5分

2.代码题(需要提交代码)

由易到难

Java:尚硅谷(Java数据结构和算法) Python:清华大学(数据结构和算法) 大话数据结构和算法(第四版) 刷题网站: 1.洛谷(难)刷官方题单 2.北京大学 poj 3.acwing 4.力扣 暴力递归+暴力搜素+真题

一、循环(前三道题涉及)

1. for循环

一般能在题目里找到循环次数

2. while循环

只知道循环条件,不知道循环次数

在考察循环时,还会涉及到集合、字符串等知识等知识点的用用。 例如:

  • 对字符串一般考察常用函数。字符串转字符数组,判断结尾等。

  • 集合一般考察特性:

    1. list:有序可重复

    2. set:无序不可重复

    3. map: key-value键值对(key不能为空,不能重复)

例题1

题目描述:有些数字的立方的末尾正好是该数字本身。 比如:1,4,5,6,9,24,25,…

请你计算一下,在10000以内的数字中(指该数字,并非它立方后的数值),符合这个特征的正整数一共有多少个。

请提交该整数,不要填写任何多余的内容。

 public class Demo2 {
     public static void main(String args[]) {
         int cubedResult, num = 0;
         for (int x = 1; x <= 10000; x++) {
             cubedResult = x * x * x;//计算变量 x 的立方并将结果存储在 cubedResult 中。
             String xStr = "" + x;//将整数变量 x 转换为字符串类型,存储在 xStr 中。
             String cubedStr = "" + cubedResult;
             boolean endsWithX = cubedStr.endsWith(xStr);//检查 cubedStr 是否以 xStr 结尾,并将结果存储在 endsWithX 中。
             if (endsWithX) {
                 num++;
             }
         }
         System.out.println(num);
     }
 }

例题2

 public class Demo3 {
     public static void main(String args[]){
         int length = 2019;
         int width=324;
         int count=0;//切出正方形的个数
                 while(true){
                     if(length>width){//长大于宽
                         length=length-width;
                         count++;
             }else if(length<width){//长小于宽
                         width=width-length;
                         count++;
                     }else if(length==width&&width!=0){
                         count ++;
                         width-=width;
                         length-=length;
                     }else if(width==0){
                         break;
                     }
                 }
                 System.out.println(count);
     }
     }
 ​
 ​
 结果:21
 Process finished with exit code 0
 ​

例题3

TIP:

  • 循环的终止条件已知==总工资>=108元,用while循环

  • 等差数列(直接暴力解题)

 public class Demo4 {
     public static void main(String[] args) {
         int sum=0;//总钱数
         int i=1;//每天挣得钱
         int day=0;//总天数
         while(true){
             sum+=i;
             day+=1;
             if(sum>=108){
                 break;
             }
             i+=2;//后一天比前一天多挣2块钱
 ​
         }
         System.out.println(day);
     }
 }
 结果:11
 Process finished with exit code 0
 ​

例题4

TIP(*4是因为拿了一堆,剩下4堆):

  • 用while循环(满足下列条件结束):

    1 .n%5=1 a=(n-1)/5*4

    2 .a%5=2 b=(a-2)/5*4

    3 .b%5=3 c=(b-3)/5*4

    4 .c%5=4 d=(c-4)/5*4

    5 .d%5=0 d>0

     public class Demo5 {
         /*
     1 .n%5=1 a=(n-1)/5*4
     2 .a%5=2 b=(a-2)/5*4
     3 .b%5=3 c=(b-3)/5*4
     4 .c%5=4 d=(c-4)/5*4
     5 .d%5=0 d>0
      */
         public static void main(String[] args) {
           int n=1;//香蕉数量
             while(true){
                 if(n%5==1){
                     int a=(n-1)/5*4;
                     if(a%5==2){
                         int b=(a-2)/5*4;
                         if(b%5==3){
                             int c=(b-3)/5*4;
                             if(c%5==4){
                                 int d=(c-4)/5*4;
                                 if(d%5==0 && d>0){
                                     break;
                                 }
                             }
                         }
                     }
                 }
                 n++;
                 }
             System.out.println(n);
             }
         }
     ​
     ​
     3141
     Process finished with exit code 0

3.字符串循环和集合的使用

对集合考察集中在集合的特性和功能。set唯一性。list有序性。以及集合元素的个数。

例题1:

TIP(set的唯一性,去除重复的子串):

  1. 下标0截取范围:【0,最大下标】

  2. 下标1截取范围:【1,最大下标】

截取的方法:subString(i,j)截取子串

 public class Demo6 {
     public static void main(String[] args) {
          String string="0100110001010001";
           HashSet<Object> set=new HashSet<>();//去重
         for(int i=0;i<string.length();i++){//从第几个下标开始截取
             for(int j=i;j<string.length();j++){
               String s= string.substring(i,j+1);
                 set.add(s);
             }
             System.out.println(set.size());//打印去重后的个数
         }
     }
 }
 结果:100

例题2:

找到一个整数i,使得i的平方和i的立方组成的字符串恰好包含10个唯一的字符,然后输出该整数i的值。在循环中,代码逐个递增检查i的值,直到找到满足条件的整数为止。

 import java.util.HashSet;
 ​
 public class Demo2 {
     public static void main(String args[]) {
         int i = 1;
         while (true) {
             HashSet<Object> set = new HashSet<>();
             int ping = i * i;
             int li = i * i * i;
             String string = ""+ping + li ;
             if (string.length() == 10) {
                 char[] cs = string.toCharArray();
                 for (int j = 0; j < 10; j++) {
                     set.add(cs[j]);
                 }
                 if (set.size() == 10) {
                     System.out.println(i);
                     break;
                 }
             }
             i++;
         }
     }
 ​
 }
 结果:69

4.循环求质数

  • 质数是只能被1和它本身整除的数字。最小的质数是2

  • 如何判断一个数字n是不是质数:找一下【2,n-1】有没有能被n整除的数字,有就不是质数。

  • 整除:n对数字取余为0

例题

 public class Demo61 {
     public static void main(String[] args) {
         ArrayList<Object> list = new ArrayList<>();
         for (int i = 2; i <= 20000; i++) {
             int a = 0;//记录有没有除了1和它本身之外可以整除的数字
             for (int j = 2; j <i; j++) {
                 if (i % j == 0) {
                     a++;
                     break;//只要找到一个能被整除的就退出内层循环,提高运算效率
                 }
             }
             if (a == 0) {//没有能被整除的
                 list.add(i);
 ​
             }
             System.out.println(list.get(2022));
         }
 ​
     }
 }
 结果:
 17597

二、排序与算法

1.排序

在一维数组中,排序是很重要的。冒泡排序,插入排序,选择排序(排序的思维不同)

冒泡排序

第一趟结束后最大的数字出现在最后一位(然后不用参与排序),第二趟结束倒数第二大的数字出现在倒数第二位(不用参与排序)

原理:比较两个相邻的元素,将较大的值交换到右边

2 8 7 5 9 4 3

第一趟:

第一次:比较2和8 (不需要交换)

第二次:比较8和7,(将8和7交换位置:2 7 8 5 9 4 3)

第三次:比较8和5,(将8和5交换位置:2 7 5 8 9 4 3)

第四次:比较8和9,(不需要交换)

第五次:比较9和4,(将9和4交换位置 :2 7 5 8 4 9 3)

第六次:比较9和3,(将9和3交换位置:2 7 5 8 4 3 9)

第二趟:

第一次:比较2和7(不需要交换)

第二次:比较7和5(需要交换 2 5 7 8 4 3 9)

第三次:比较7和8(不需要交换)

第四次:比较8和4(需要交换 2 5 7 4 8 3 9)

第五次:比较8和3(需要交换 2 5 7 4 3 8 9)

第六次:比较8和9(不需要交换)?

第三趟:

第一次:比较2和5(不需要交换)

第二次:比较5和7(不需要交换)

第三次:比较7和4(需要交换 2 5 4 7 3 8 9)

第四次:比较7和3(需要交换 2 5 4 3 7 8 9)

第五次:比较7和8(不需要交换)

第六次:比较7和9(不需要交换)

 public class Demo11 {
     public static void main(String[] args) {
         //外层for循环控制趟,内层控制次数
         int a[]={10,1,35,61,89,36,55};
         for (int i = 0; i < a.length-1-i; i++) {//趟的次数是确定的
             for (int j = 0; j <a.length-1; j++) {
                 //判断相邻的两个数字
                 if(a[j]>a[j+1]){
                     //交换位置
                     int k = a[j];
                     a[j] = a[j+1];
                     a[j+1] = k;
                 }
             }
         }
         for(int i=0;i<a.length;i++){
             System.out.println(a[i]+"");//遍历
         }
     }
 }
 ​

选择排序

原理:

第一次:从未排序的数据元素里面,选出一个最小的(最大的)的元素,然后和第一位元素交换位置;

第二次:从未排序的数据元素里面,选出一个第二小的(第二大的)的元素,然后和第二位元素交换位置;

。。。。以此类推

 public class Demo31 {
     public static void main(String[] args) {
         int a[] = {2, 9, 5, 0, 1, 3, 6, 8};
         int begin = 0;
         int end = a.length - 1;
         while (begin < end) {
             int min = a[begin];//min用来存储数组元素中的最小值
             int t = begin;//min的下标
             for (int i = begin; i <= end; i++) {
                 if (min > a[i]) {
                     min = a[i];
                     t = i;
                 }
             }
             a[t] = a[begin];
             a[begin] = min;
             begin++;
         }
         for (int i = 0; i < a.length; i++) {
             System.out.println(a[i] + "");//遍历
         }
     }
 }
 ​

插入排序

原理:将数列分为两个部分:排好序的数列 未排序的数列

在未排序的数列里,挨个去插入到排好序的数列里面

 public class Demo22 {
     public static void main(String[] args) {
         int a[] = {2, 1, 6, 4, 9, 7, 6, 8};
         //为排好序的数组
         for (int i = 1; i < a.length; i++) {
             int k = a[i];//哨兵。从数组第二位元素开始,每一循环向后移动一位存储元素,将这个数插入排号数的数列中
             int j = i - 1;//排好序数列中的最后一位元素的下标(i是未排好序里面的第一位)
             while (j >= 0 && k < a[j]) {//哨兵要存在左边比他小,右边比它大
                 a[j + 1] = a[j];//给哨兵插入腾出位置
                 j--;//用j记录哨兵最终插入的位置
             }
             a[j + 1] = k;//哨兵插入
 ​
         }
         for (int i = 0; i < a.length; i++) {
             System.out.println(a[i] + "");//遍历
         }
     }
 }
 ​

2.排序

递归

函数/方法 直接/间接 的调用本身。一般用来在原来的基础上加减乘除等操作

案例:斐波那契数列:

1 1 2 3 5 8 13……第一和第二个数字是1,其他数字等于前两个数字之和。Fn=F(n-1)+F(n-2)

代码:计算第n位的斐波那契数字

     //递归:代码简洁,但是涉及的运算会随着递归层数的增加而指数增长,效率低下
     public static int Fn(int n){
         if(n==1||n==2){
             return 1;
         }
         return Fn(n-1)+Fn(n-2);
     }
 }
 ​

例题

第20行第20列相当于这个数列的第20位数字。

 public class Demo33 {
  public static void main(String[] args) {
      System.out.println(snack(20));
  }
  public static int snack(int n){
      if(n==1){
          return 1;
      }
      return snack(n-1)+4*(n-1);
  }
 }

记得找规律

问题:递归和循环的关系?

一道题可以用递归(代码简洁、但是时间复杂度大)解答,也可以换成循环(代码量变多、运算资源减少了、降低了时间复杂度)来解决

如果发现题目使用递归超出了限制,那么:

  • 换循环;

  • 加字典;

 public class Demo0 {
     public static void main(String[] args) {
         System.out.println(Fn(20));
     }
     //递归:代码简洁,但是涉及的运算会随着递归层数的增加而指数增长,效率低下
     public static int Fn(int n){
         if(n==1||n==2){
             return 1;
         }
         return Fn(n-1)+Fn(n-2);
     }
 }


思考:用辗转相除法求最大公约数 
  • 27
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值