2022java蓝桥杯算法训练

1.印章:

 

代码:

复制代码
 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         Scanner s=new Scanner(System.in);
 6         int n=s.nextInt();
 7         int m=s.nextInt();
 8         double p=1.0/n;
 9 
10         double[][] b=new double[m+1][n+1];
11         if (n==1){  //当n=1时m>n几率为1
12             b[m][n]=1;
13             System.out.printf("%.4f",b[m][n]);
14             return;
15         }
16         if (n>1&&m<n){ //当m<n时几率为0
17             b[m][n]=0;
18             System.out.printf("%.4f",b[m][n]);
19             return;
20         }
21         for (int i = 1; i <=m; i++) {
22             for (int j = 1; j <=n; j++) {
23                 if (i<j) b[i][j]=0;       //当m<n时几率为0
24                 if (j==1){
25                     b[i][j]=Math.pow(p,i-1);        //当i张集齐1种的概率
26                 }else {
27                     b[i][j]=b[i-1][j]*(j*1.0/n)+b[i-1][j-1]*((n-j+1)*1.0/n);        //当i张集齐j种的概率
28                 }
29 
30             }
31 
32         }
33 
34         System.out.printf("%.4f",b[m][n]);
35 
36     }
37 }
View Code
复制代码

 

2.拿金币:

代码:

复制代码
 1 import java.util.Scanner;
 2 
 3 
 4 public class Main {
 5 
 6     /*
 7     * 输入:第一行,整数n,表示N*N的一个矩阵。
 8     *       n行,初始化,每个矩阵的大小。每个数不能找过1000. short类型。
 9     * 格式要求:n小于1000 short类型
10     * */
11 
12     /*
13     * 输出:一行整数sum,表示的是矩阵从左上角到右下角的最大和。 int类型
14     * w*/
15 
16     //程序思路:
17         //1.接受n,创建一个数组
18         //2.初始化数组。
19         //3.求和。
20 
21     public static void main(String[] args){
22         //1.接受n,创建一个数组
23         Scanner input = new Scanner(System.in);
24         short n = input.nextShort();
25 
26         //2.初始化数组。
27         int[][] arrys = new int[n][n];
28         for (int i = 0; i <n ; i++) {
29             for (int j = 0; j <n ; j++) {
30                 arrys[i][j] = input.nextInt();
31 
32             }
33 
34         }
35 
36 
37 
38 
39 
40 
41 
42 
43         //3.求和
44         for (int i = 0; i < n; i++) {
45             for (int j = 0; j < n; j++) {
46                 //初始化固定部分,arrys[0][0]-a[0][n-1]。a[0][0]-a[n-1][0]。
47                 //因为从这一部分走,方向是唯一,也就是和是唯一的,没有别的路。
48                 if (i==0&&j==0)//初始化首位。
49                     continue;
50 
51 
52                 if (i == 0) {//首行非首位。
53                     arrys[i][j] =  (arrys[i][j-1]+arrys[i][j]);//运算+ - 至少要int类型,所以会被强制转换,而不是下标问题。
54                     continue;
55 
56                 }
57 
58                 if (j == 0) {//首列,非首位。
59                     arrys[i][j] = (arrys[i-1][j]+arrys[i][j]);
60                     continue;
61                 }
62 
63                 if (arrys[i - 1][j] > arrys[i][j - 1]) {//上比左大。
64                     arrys[i][j] = (arrys[i][j]+arrys[i-1][j]);
65                 }else arrys[i][j] =(arrys[i][j]+arrys[i][j-1]);//左比上大。
66 
67 
68             }
69         }
70 
71 
72                 System.out.println(arrys[n-1][n-1]);
73 
74         }
75 
76     }
View Code
复制代码

3.数字游戏:

代码:

复制代码
 1 import java.util.Scanner;
 2 /*
 3  *
 4  * */
 5 public class Main {
 6 
 7     static int n;//初始的n个数
 8     static int sum;//相加的结果
 9     static int arr1[];
10     static boolean bool = true;//标记是否找到n个元素
11 
12     public static void main(String[] args) {
13         Scanner sc = new Scanner(System.in);
14         n = sc.nextInt();
15         sum = sc.nextInt();
16 
17         int array[] = new int[n];
18         int visit[] = new int[n+1]; //访问标记
19 
20         dfs(0, array, visit);
21     }
22 
23     //step:当前已经遍历的元素数;array:存放当前遍历的元素; visit:标记当前哪些元素已被访问;
24     public static void dfs(int step,int arr[], int vis[]){
25         if(step == n){//1.找到n个数字,检查这n个数相加是否等于sum
26             int arr1[] = new int[n];
27             for(int i=0;i<n;i++){//先将array数组中的元素 放到arr1
28                 arr1[i] = arr[i];
29             }//for
30 
31             for(int i=1;i<n;i++){//累加到arr1[0]
32                 for(int j=0;j<n-i;j++){
33                     arr1[j]=arr1[j]+arr1[j+1];
34                 }
35             }//for
36 
37             if(arr1[0] == sum){//累加后与sum相等,则输出
38                 for(int i:arr){
39                     System.out.print(i+" ");
40                 }
41                 bool = false;//已经找到符合要求的n个元素
42                 return;
43             }else{//累加后与sum不相等,退出重新查找
44                 return;
45             }
46 
47         }//if
48         if(bool == true){//2.没有找到符合要求的n个元素
49             for(int i=1;i<=n;i++){
50                 if(vis[i]==0){//i值没有使用过
51                     arr[step]=i;//存储当前访问的元素
52                     vis[i]=1;
53                     dfs(step+1,arr,vis);//从当前这个元素起,重新进行遍历
54                     vis[i]=0;
55                 }
56             }
57         }//if
58         return;
59     }
60 }
View Code
复制代码

4.无聊的逗:

代码:

复制代码
 1 import java.util.Scanner;
 2 public class Main {
 3     public static void main(String[] args) {
 4         Scanner cin=new Scanner(System.in);
 5         int ans=Integer.MIN_VALUE;
 6         int n = cin.nextInt();
 7         int []array=new int[1<<n];
 8         int []nums=new int[n];
 9         for(int i=0;i<n;++i){
10             nums[i]=cin.nextInt();
11             array[1<<i]=nums[i];
12         }
13         for(int i=0;i<1<<n;++i){
14             for(int j=0;j<n;++j){
15                 if((i&(1<<j))==0)continue;
16                 array[i]=array[i-(1<<j)]+nums[j];
17                 break;
18             }
19         }
20         for(int i=1;i<(1<<n);++i){
21             int j=(1<<n)-i-1;
22             for(int k=j;k>0;k=(k-1)&j){
23                 if(array[k]==array[i])
24                     ans=Math.max(array[k],ans);
25             }
26         }
27         System.out.print(ans);
28     }
29 }
View Code
复制代码

5.礼物:

思路:

  a.只能拿一次,2k,从开头拿起。所以分为前k0,后k1,并且两者要相等。k0 和k1 都要小于s。最后再输出.k的值。

  b.在循环赋值当中,保存每一项累加的结果到数组当中

  c.通过二分查找的方式找到前面的k0的大小,再匹配后面k1的总和是否也满足,满足就直接输出,不满足就降低k0的值来重新寻找。

 

代码:

复制代码
 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 public class Main{
 5     static int count =0;
 6     static long S;
 7     public static void main(String args[]) {
 8         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 9         String s,s2;
10         String[] b1 = null,b2 = null;
11         try {
12                 s=br.readLine();
13                 b1=s.split(" ");
14                 s2=br.readLine();
15                 b2=s2.split(" ");
16     
17         } catch (IOException e) {
18             // TODO Auto-generated catch block
19             e.printStackTrace();
20         }
21         int N=Integer.parseInt(b1[0]);
22         S=Long.parseLong(b1[1]);
23         
24         int[] a=new int[N+1];
25         long[] sum=new long[N+1];
26         for(int i=1;i<=b2.length;i++) {
27             a[i]=Integer.parseInt(b2[i-1]);
28             sum[i]=sum[i-1]+a[i];
29         }
30         int l=1,r=N;
31         while(l<r) {
32             int mid=(l+r+1)/2;
33             if(fun(mid,N,sum)) {
34                 l=mid;
35             }else {
36                 r=mid-1;
37             }
38         }
39         System.out.print(2*l);
40     }
41     public static boolean fun(int mid,int n,long[] sum) {
42         for(int i=mid;i<=n-mid;i++) {
43             if(sum[i]-sum[i-mid]<=S&&sum[i+mid]-sum[i]<=S) {
44                 return true;
45             }
46         }
47         return false;
48     }
49 }
View Code
复制代码

 

 总结:

  a.Scanner 类不适合输入太多的值的情况,容易引起内存过大,这时可以考虑BufferedReader类来完成输入流的操作。归属java.io.BufferedReader.和java.io.InputStreamReader

用法是 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)

String s =br.readLine()//读取一整行。

String[] ss = s.split(" ")//根据空格来分割字符串为数组。

  b.考虑大小,数组可以是int 类型,但是求和的时候可能会超过,所以最好用long数组。

  c.paresInt 和parselong 参数一样,都是用的是字符串,最后转换为整形类型,虽然输出的的时候还是字符串,所以可以根据是否要用于做运算来抉择,加减乘除的运算至少是int类型才能,所以byte ,short适合不做运算的情况来使用,避免频繁装箱。

 6.跳马:

  代码如下:

  

复制代码
 1 import java.util.*;
 2 
 3 import static java.lang.System.in;
 4 import static java.lang.System.out;
 5 
 6 public class Main {
 7     static Deque<int[]> list = new LinkedList<int[]>(); // 这个集合记录每一次走的过程,因为只涉及插入和删除,我用Deque。
 8     static int[][] steps = new int[][]{{1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {2, 1}, {2, -1,}, {-2, 1},
 9             {-2, -1}};  // 因为马只能走“日”,所以这个二维数组给出所有马能够走的方向,共八方。
10 
11     public static void main(String[] args) {
12 
13         Scanner sc = new Scanner(System.in);
14         int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt(), d = sc.nextInt(), len = steps.length;
15         out.println(getCount(a, b, c, d, len));
16     }
17 
18     /**
19      * @param a 对应题目中的a
20      * @param b 对应题目中的b
21      * @param c 对应题目中的c
22      * @param d 对应题目中的d
23      * @param len steps数组的长度
24      * @return 返回最短的次数
25      */
26     public static int getCount(int a, int b, int c, int d, int len) {
27         list.offer(new int[]{a, b}); // 先将起始位置加进来
28         int count = 0, innerCount = 0; //count为最后的返回值,innerCount后面会讲
29         if (list.getFirst()[0] == c && list.getFirst()[1] == d) { // 如果起始位置等于最终的位置,我们直接返回count。
30             return count;
31         }
32 
33         boolean flag = true;  // 死循环退出标识
34         while (flag) {
35             for (int i = 0; i < len; i++) {  // 最外层的for循环是控制马走的方向
36                 int[] at = new int[2]; // 临时的at数组装载每一次当前位置的下一个位置
37                 for (int j = 0; j < 2; j++) { // 该循环每次都更新马当前位置可走的方向,比方说马当前在(1,1),完成一次该for循环,马就出现了下一个可以走的位置,存到list里面,
38                                                 // 如果两层for循环都完成马就会出现8个当前位置可以走的下一个位置,存入list中
39                     at[j] = list.getFirst()[j] + steps[i][j];
40                 }
41                 list.offer(at); // 存入下一个位置到list
42                 innerCount++; // 每一个存入innerCount就会+1,当这里的加1并不能表示次数。因为如果马用的步数为1的时候,innerCount的会是8,而步数用的是2时,innerCount为64
43                 if (at[0] == c && at[1] == d) { // 符号条件,则把退出表示设置为false
44                     flag = false;
45                     break;
46                 }
47             }
48             if (Math.pow(8, count + 1) == innerCount) // 基于42行的说法,所以有了当前的判别式。
49                 count++;
50             list.pollFirst(); // 当当前位置下一步可走的8个方向存入list中,我们删除当前方向,判别下一个方向
51         }
52         return count + 1;
53     }
54 
55 }
View Code
复制代码

7.kAc给糖果你吃

代码如下:

复制代码
 1 import java.util.Scanner;
 2 public class Main {
 3 
 4 /*
 5 * 输入:两行,第一行n(表示有多少堆),m(表示拿的次数)
 6 *           第二行:n个数字(初始化每堆糖果的个数)
 7 * 格式要求:n在0--1000,其他的是10亿。(int类型)
 8 * */
 9 
10     /*
11     * 输出:一行,整数,s,表示最多拿多少糖果。
12     * */
13 
14 
15 
16 
17 //程序:
18 
19 
20 
21 
22         public static void main(String[] args){
23 
24             //1.接收n,m,初始化数组。
25             Scanner input = new Scanner(System.in);
26             int n = input.nextInt(); //n
27 //            System.out.println("n:"+n);
28             int m = input.nextInt(); //m
29 //            System.out.println("m:"+m);
30             int[] array = new int[n];//A【i】
31             long sum = 0;//sum
32             for(int i =0 ; i<n ; i++){
33                 array[i] = input.nextInt();
34 //                System.out.println(array[i]);
35             }//for
36 
37             //2.查找m次最大值,使用选择排序
38             for(int i=0; i<m;i++){
39                 for(int j = i+1;j<n;j++){
40                     if(array[i]<array[j]){
41                         //交换
42                         int temp = array[j];
43                         array[j] = array[i];
44                         array[i] = temp;
45                     }//if
46 
47                     //把每次最大值相加;
48 
49                 }//for
50                 sum = sum + array[i];
51             }//for
52 
53             System.out.println(sum);
54         }//main
55     }//
View Code
复制代码

8.数的潜能:

代码如下:

复制代码
 1 import java.util.Scanner;
 2 public class Main{
 3     public static void main(String args[]) {
 4         Scanner sc=new Scanner(System.in);
 5         long n=sc.nextLong();
 6         //a 3的数量,b 2的数量
 7         long a=0;
 8         int b=0;
 9         int[] x=new int[100];
10         long[] z=new long[100];
11         //a 3的数量,b 2的数量
12         if(n%3==1) {
13             a=(n/3)-1;
14             b=2;        
15         }else if(n%3==2) {
16             a=n/3;
17             b=1;
18         }else {
19             a=n/3;
20         }
21         //c a个3相乘取模的当前位置 x[]与z[]记录相应的取模值及取模位置,d 后一半剩余相乘数量。
22         long c=1;
23         int yu=3%5218;
24         int k=0;
25         x[0]=yu;
26         z[0]=c;
27         while(a>=2*c) {
28             yu=(yu*yu)%5218;
29             x[++k]=yu;
30             c*=2;
31             z[k]=c;
32         }
33         long d=a-c;
34         for(int i=k-1;i>=0;i--) {
35             if(d>z[i]) {
36                 yu=(yu*x[i])%5218;
37                 d=d-z[i];
38             }
39         }
40         yu=(int) ((yu*Math.pow(3, d)*Math.pow(2, b))%5218);
41         System.out.print(yu);
42     }    
43 }
View Code
复制代码

9.娜神平衡

代码如下:

复制代码
 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5     static int N;// 数据的总个数
 6     static int R;// 相差不能超过R
 7     static int[] A;// A存放元素的数组
 8     static int[] B;// B存放元素的数组
 9     static int[] vis;// 数据被使用的状态
10     static int a = 0;// A的元素
11     static int b = 0;// B的元素
12     static int flag = 0;// 结束标志,题目告知答案唯一,所以找到答案后就结束。
13 
14     public static void main(String[] args) {
15         Scanner scanner = new Scanner(System.in);
16         int n = scanner.nextInt();
17         N = n;
18         vis = new int[n];
19         int r = scanner.nextInt();
20         R = r;
21         A = new int[n];
22         B = new int[n];
23         int[] arr = new int[n];
24         for (int i = 0; i < n; i++) {
25             arr[i] = scanner.nextInt();
26         }
27         DFS(arr, 1);
28     }
29 
30     // 求和
31     public static int sum(int[] num) {
32         int sum = 0;
33         for (int x : num) {
34             sum += x;
35         }
36         return sum;
37     }
38 
39     // 深度搜索
40     public static void DFS(int[] arr, int step) {
41         if (Math.abs(sum(A) - sum(B)) > R) {//不符合题目条件的直接返回结束
42             return;
43         }
44         if (step > N) {//找到答案
45             //对A、B数组进行从小到大的排序
46             Arrays.sort(A, 0, a - 1);
47             Arrays.sort(B, 0, b - 1);
48             //输出结果
49             for (int i = 0; i < a; i++) {
50                 System.out.print(A[i] + " ");
51             }
52             System.out.println();
53             for (int i = 0; i < b; i++) {
54                 System.out.print(B[i] + " ");
55             }
56             flag = 1;//修改结束标志
57             return;
58         }
59         //先往A里面放元素,直到放进A不满足条件 A-B的绝对值<r
60         for (int i = 0; i < N; i++) {
61             if (flag == 1) {// 先判断结束标志
62                 return;
63             }
64             if (vis[i] == 0) {
65                 A[a++] = arr[i];
66                 vis[i] = 1;
67                 DFS(arr, step + 1);//放下一个
68                 A[--a] = 0;
69                 vis[i] = 0;
70             }
71         }
72 
73         //放完A后,往B放元素 
74         for (int i = 0; i < N; i++) {
75             if (flag == 1) {// 先判断结束标志
76                 return;
77             }
78             if (a == 0) {//题目中要求先往A放,所以放入B时先检测A里面有没有元素
79                 return;
80             }
81             if (vis[i] == 0) {
82                 B[b++] = arr[i];
83                 vis[i] = 1;
84                 DFS(arr, step + 1);//放下一个
85                 B[--b] = 0;
86                 vis[i] = 0;
87             }
88         }
89     }
90 
91 }
View Code
复制代码

10.粘木棍

代码如下:

复制代码
 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5 
 6 static int mm;
 7 public static void main(String args[]) {
 8 Scanner sc=new Scanner(System.in);
 9 int N=sc.nextInt();
10 int M=sc.nextInt();
11 int[] a=new int[N];
12 for(int i=0;i<N;i++) {
13 a[i]=sc.nextInt();
14 //总长度
15 mm+=a[i];
16 }
17 int[] b=new int[M];
18 //b 记录每根木棍长度,c记录木棍是否使用
19 fun(a,b,0,N,M);
20 System.out.print(mm);
21 }
22 public static void fun(int[] a,int[] b,int k,int n,int m) {
23 //如果还有木棍
24 if(k<n) {
25 //遍历数组b
26 for(int i=0;i<m;i++) {
27 //暂时将这个木棒加到当前的木棒组上
28 b[i]+=a[k];
29 //继续往下调用函
30 fun(a,b,k+1,n,m);
31 //在这个木棒组上去下当前木棒,以便在下一木棒组上使用
32 b[i]-=a[k];
33 }
34 }else {//当木棒全部粘完时
35 //找出当前所有木棒组里最小值和最大值
36 int max=b[0],min=b[0];
37 for(int i=0;i<m;i++) {
38 if(b[i]>max) {
39 max=b[i];
40 }
41 if(b[i]<min) {
42 min=b[i];
43 }
44 }
45 if(max-min<mm) {
46 mm=max-min;
47 }
48 }
49 }
50 }
View Code
复制代码

11.车的放置

代码如下:

复制代码
 1 import java.io.*;
 2  
 3 public class Main {
 4     public static void main(String[] args) throws NumberFormatException, IOException {
 5         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 6         int n = Integer.parseInt(br.readLine());
 7         Temp996b temp = new Temp996b(n);
 8         temp.dfs(1);//从第一行开始摆放
 9         System.out.println(temp.ans);
10     }
11 }
12 class Temp996b{
13     int n;
14     int ans = 1;
15     boolean visited[] = new boolean[9];//表示第几列是否摆放
16     
17     public Temp996b(int n) {
18         this.n = n;
19     }
20     
21     public void dfs(int step) {//表示棋子应放到第temp行
22         if(step > n) {//递归出口:当前摆放行数超出棋盘总行数
23             return;
24         }
25         for(int i = 1; i <= n; i++) {
26             if(!visited[i]) {//step行的第i列为空
27                 visited[i] = true;//已放置
28                 ans++;
29                 dfs(step + 1);//递归至下一行摆放
30                 visited[i] = false;//回溯:将step行重置
31             }
32         }
33         dfs(step + 1);//有空行情况,将step行跳过(不摆放)
34     }
35 }
View Code
复制代码

12.24点:

代码如下:

无。。。

13.最大分解:

代码如下:

复制代码
 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args){
 6 
 7         //a0的值
 8         Scanner input= new Scanner(System.in);
 9         int a0 = input.nextInt();
10         int[] a = new int[a0];
11         a[0] = a0;
12         int sum = 0 ;
13         int j = 0;
14 
15         //找值。
16         for (int i = a0-1; i >=1 ; i--) {
17             if(a[j]%i==0){
18                 //把数存起来,下标+1.
19                 sum += i;
20                 j++;
21                 a[j] = i;
22             }
23         }
24         System.out.println(sum);
25 
26     }
27 
28 
29 }
View Code
复制代码

14.RP大冒险

代码如下(没看懂,随便写的)

复制代码
 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args){
 6 
 7 
 8 
 9             int[] a = {0,1,2,3,4,5,6,7,8,9
10             };
11             int b = new Scanner(System.in).nextInt();
12 
13     System.out.println(a[b]);
14 
15 
16     }
17 
18 
19 }
View Code
复制代码

 

待更新。。。

 

posted @   星辉与你  阅读(316)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
点击右上角即可分享
微信分享提示