蓝桥杯

共识:代码提交题 没有思路优先想暴力 没有暴力思路先跳 去看后面的 (暴力都写不出来那就没办法咯)

2019蓝桥杯

2.不同字串:

3.数列求值

  1. package lanqiaobei;
  2. import java.util.Scanner;
  3. public class yanhuisanjiao {
  4. public static void main(String[] args) {
  5. Scanner input=new Scanner(System.in);
  6. int a=1;
  7. int b=1;
  8. int c=1;
  9. //试了一下long也能爆,还是取摸吧
  10. //前面三项已经有了,从第四项开始
  11. for(int i=4;i<=20190324;i++){
  12. int temp=((a+b+c)%10000);
  13. a=b;
  14. b=c;//依次往后移
  15. c=temp;
  16. }
  17. System.out.println(c);
  18. }
  19. }

4.数的分解:

7.外卖优先级

算法思路:

由分析可知,如果我们可以建立一张店铺订单数量和时刻相关联的表,则可以很清楚的计算各时刻各店铺的优先级数。因而我们可以借助二维数组orderTable(店铺id为行,时刻t为列)来表示该表,然后遍历该数组并逐个计算各时刻下各店铺的优先级数,如果符合条件则加入map中并以店铺id为key值,若不符合条件则将其移出,最后查看map中有多少项,即可。

具体编码

public class waimaiyouxianji {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            int shops = input.nextInt();//店铺数量
            int orders = input.nextInt();//订单数量
            int time = input.nextInt();//T时刻
            int[][] orderTable = new int[shops+1][time+1];//存储各店铺各时刻的订单数量
            int[] shopCounts = new int[shops+1];//T时刻,店铺的优先级数
            HashMap<Integer,Integer> shopMap = new HashMap();//作为优先缓存
            for (int i = 0; i < orders; i++) {
                int ts = input.nextInt();//订单时刻
                int id = input.nextInt();//接收订单的店铺

                if(ts <= time){//在T时刻表中的订单状态
                    orderTable[id][ts]++;
                }
            }
            for (int i = 1; i <= shops; i++) {
                for (int j = 1; j <= time; j++) {
                    if(orderTable[i][j] == 0){
                        shopCounts[i] = Math.max(0,shopCounts[i] - 1);//当店铺i在j时刻,无订单且优先级数不为零时自减1
                    }else{
                        shopCounts[i] += orderTable[i][j] * 2;//当店铺i在j时刻,有订单则将此时刻该店铺的订单数量×2
                    }
                    //判断优先级数,确定是否加入优先缓存
                    if(shopCounts[i] > 5){//当店铺优先级数首次大于5时将其加入优先缓存中
                        shopMap.put(i,1);
                    }else if(shopCounts[i] <= 3 && shopMap.containsKey(i)){//当店铺已经加入到优先缓存且优先级数小于等于3时,剔除出去
                        shopMap.remove(i);
                    }
                }
            }
            System.out.println(shopMap.size());//此时map的大小即为优先缓存中的店铺数量
        }
    }

8.人物相关性格分析

题目描述:

题解:

package lanqiaobei;

import java.util.Scanner;

public class renwuxiangguangxinggefenxi {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int k=sc.nextInt();
        sc.nextLine();//?
        String str=sc.nextLine();
        //分割语句存放到words中
        String[] words=str.split("\\s|\\.");
        //System.out.println(Arrays.toString(words));
        int[] wordslength=new int[words.length];
        for (int i = 0; i < wordslength.length; i++) {
            //将分割后每一个单词的长度存放到wordslength中
            wordslength[i]=words[i].length();
        }
        int num=0;
        //Alice---Bob
        for (int i = 0; i < words.length; i++) {
            //如果找到Alice
            if(words[i].equals("Alice")){
                for (int j = i+1; j < words.length; j++) {
                    //因为Alice后有一个空格而j从Alice后面一个单词开始所以sum=1
                    int sum=1;
                    if(words[j].equals("Bob")){
                        //将Alice和Bob之间的长度累加给sum
                        for (int l = i+1; l < j; l++) {
                            //每个长度+1是因为中间有空格或者.
                            sum+=wordslength[l]+1;
                        }
                        if(sum<k){
                            num++;
                        }
                    }
                }
            }
        }
        //Bob---Alice
        //将上面代码cv一下判断条件Alice和Bob调换一下
        for (int i = 0; i < words.length; i++) {
            if(words[i].equals("Bob")){
                for (int j = i+1; j < words.length; j++) {
                    int sum=1;
                    if(words[j].equals("Alice")){
                        for (int l = i+1; l < j; l++) {
                            sum+=wordslength[l]+1;
                        }
                        if(sum<k){
                            num++;
                        }
                    }
                }
            }
        }

        System.out.println(num);
    }

}

9.后缀表达式

题目描述:

算法思路

在求解该题时,我们应该清楚一点,后缀表达式与前缀表达式在计算过程中是可以存在括号“()”的。明确这一点后,我们就可以很清楚的找到结果最大的值,此值即为所有数值之和减去最小数值的两倍。举个例子帮大家理解一下:a+b-(c-d-e) = a+b-c+d+e = a+b+c+d+e-2*c,如果此时c为a、b、c、d、e中的最小值,那么此时的a+b-(c-d-e)显然为a、b、c、d、e与+、-各组合结果中的最大结果。

题解:

package lanqiaobei;

import java.math.BigInteger;
import java.util.Scanner;

/*后缀表达式*/
public class houzhuibiaodashi {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            int n = input.nextInt();//n个加号
            int m = input.nextInt();//m个减号
            BigInteger sum = new BigInteger("0");//全部数值之和
            BigInteger min = new BigInteger("1000000000");//定义一个最小变量,用于保存数值中最小的那个值
            for (int i = 0; i < n+m+1; i++) {
                BigInteger temp = new BigInteger(input.next());
                sum = sum.add(temp);//求和
                if(min.compareTo(temp) == 1){//min > temp,则修改min值
                    min = temp;
                }
            }
            System.out.println(sum.subtract(min.multiply(new BigInteger("2"))));//全部数值之和减去2倍的最小数值
        }
    }

5.迷宫(题型需要练)

题目描述:

使用集合框架:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class migong {
    public static void main(String args[]) {
        // BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        migong migong = new migong();
        migong.receiveData();
        migong.bfs();
        migong.print(migong.getPath());
    }

    // 坐标类
    class P {
        int x;
        int y;

        P(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    final int INF = 100000000;// 一个足够大的数,表示未访问
    char[][] maze = new char[3][];// 表示迷宫的字符串数组
    int N = 3, M = 3;
    int sx = 0, sy = 0;// 起点坐标
    int gx = 2, gy = 2;// 终点坐标

    P[][] prev = new P[3][3];// 坐标x,y在路径上的前驱(前一个坐标)prev[x][y]
    int[][] d = new int[3][3];// 到各个位置的最短距离的数组

    int dx[] = { 1, 0, 0, -1 }, dy[] = { 0, -1, 1, 0 };// D,L,R,U 下,左,右,上 移动方向

    // 接受数据
    void receiveData() {
        Scanner reader = new Scanner(System.in);
        for (int i = 0; i < N; i++) {
            maze[i] = reader.nextLine().toCharArray();
        }
    }

    // 求从(sx,sy)到(gx,gy)的最短路径
    void bfs() {
        Queue<P> queue = new LinkedList<P>();
        for (int i = 0; i < 3; i++) {// 初始化为INF
            Arrays.fill(d[i], INF);
        }
        // 将起点加入队列,并将其最短距离设为0
        queue.offer(new P(sx, sy));
        d[sx][sy] = 0;

        // 不断循环直到队列为空
        while (!queue.isEmpty()) {
            P p = queue.poll();// 取出队首元素并且再队列中删除此元素
            if (p.x == gx && p.y == gy)
                break;// 如果是终点,结束循环

            // 四个方向的循环
            for (int i = 0; i < 4; i++) {
                int nx = p.x + dx[i], ny = p.y + dy[i];// 移动后的位置记为nx,ny
                // 判断是否可以移动以及是否被访问过(d[nx][ny] == INF表示未被访问)
                if (0 <= nx && nx < N && 0 <= ny && ny < M && maze[nx][ny] != '1' && d[nx][ny] == INF) {
                    // 可以移动则加入队列,并且该坐标的最短距离为p的最短距离+1,该坐标的前驱为p
                    queue.offer(new P(nx, ny));
                    d[nx][ny] = d[p.x][p.y] + 1;
                    prev[nx][ny] = p;
                }
            }
//            return d[gx][gy]; 如果要求最短路径长度,d[gx][gy]就是最短路径长度
        }
    }

    // 到顶点t的最短路
    ArrayList<P> getPath() {
        P t = new P(gx, gy);
        ArrayList<P> path = new ArrayList<P>();
        for (; t != null; t = prev[t.x][t.y])
            path.add(t); // 不断沿着t = prev[t.x][t.y]走直到t=起点
        Collections.reverse(path);// 这样得到的是t到起点的顺序,所以翻转之
        return path;
    }

    void print(ArrayList<P> path) {
        P t = new P(sx, sy);
        for (int i = 0; i < path.size(); i++) {
            int xL = path.get(i).x - t.x, yL = path.get(i).y - t.y;// 求出移动方向
            for (int j = 0; j < 4; j++) {
                if (xL == dx[j] && yL == dy[j]) {// 方向匹配则输出
                    switch (j) {
                    case 0:
                        System.out.print('D');
                        break;
                    case 1:
                        System.out.print('L');
                        break;
                    case 2:
                        System.out.print('R');
                        break;
                    case 3:
                        System.out.print('U');
                        break;
                    }
                }
            }
            t = path.get(i);
        }
    }
}

6.特别数的和

10.灵能传输(未写)

2020蓝桥杯

斐波那契数列的最大公约数

题目描述:

题解:为了防止数字越界 因此选取BigInteger 其可以取到无线大的数 因此不存在越界 重难点:熟记api

package lanqiaobei;

import java.math.BigDecimal;
import java.math.BigInteger;

import static java.awt.Event.F1;

/*斐波那契数列最大公约数*/
public class array {
    public static void main(String[] args) {
            BigInteger arr[] = new BigInteger[2021]; // int long型数据均会爆数组
            arr[0] = BigInteger.ZERO;
            arr[1] = arr[2] = BigInteger.ONE;
            for (int i = 3; i <= 2020; i++) {
                arr[i] = arr[i - 1].add(arr[i - 2]);
            }
            System.out.println(arr[520]);
            System.out.println(arr[2020]);
            System.out.println(arr[2020].gcd(arr[520]));
        }
        public static BigInteger gcd(BigInteger a, BigInteger b) {
            return b.equals(BigInteger.ZERO) ? a : gcd(b, a.mod(b));
        }
        }

合并检测

题目描述:

方法一:

假设A国有n个人,感染者有n/100

每k个人一组,共n/k组,共用n/k瓶试剂

按照最坏的情况,每多出一个感染者就多用k瓶试剂,

因此共用n/k+(n/100)*k瓶试剂
n是定值,

所以求(1/k+k/100)最小
由于a+b>=2√ab
当且仅当a = b时,取等号

即1/k=k/100时,取得最小值
解得k = 10

方法二:

思路:假设法,假设A国只有100个人,然后k=1....100,求k在不同数字下耗费的最少

重点在于假设法

package lanqiaobei;
/*分组检测*/
public class sortCheck {
    public static void main(String[] args) {
        int min = 999990;
        int ans = -1;
        for (int i = 1; i <= 100; i++) { // i个人一块测
            int temp;
            if (100 % i != 0) {
                temp = 100 / i + i + 1;
            } else {
                temp = 100 / i + i;
            }
            if (min > temp) {
                min = temp;
                ans = i;
            }
        }
        System.out.println(ans);
    }
        }

分配口罩

题目描述:

思路:全排列

package lanqiaobei;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

public class 分配口罩 {
        public static int res=Integer.MAX_VALUE;
        public static int num[]={9090400, 8499400, 5926800, 8547000, 4958200,
                4422600, 5751200, 4175600, 6309600, 5865200,
                6604400, 4635000, 10663400, 8087200, 4554000
        };
        public static void main(String[] args){
            dfs(0, 0, 0);
            System.out.println(res);
        }
        public static void dfs(int k,int sum1,int sum2 ) {
            if(k==15) {
                res=res<Math.abs(sum1-sum2)?res:Math.abs(sum1-sum2);
                return;
            }
            dfs(k+1, sum1+num[k], sum2);
            dfs(k+1, sum1, sum2+num[k]);
        }
    }

这道题的核心,全排列+数字越界问题+深度优先搜索

分类计数(ac)

题目描述:

编码:

package lanqiaobei;

import java.util.Scanner;

public class Sortjishu {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        int big=0;
        int small=0;
        int shuzi=0;
        for (int i=0;i<s.length();i++){  
                if (s.charAt(i)>='a'&&s.charAt(i)<='z'){  //97-122
                    small++;
                }
            if (s.charAt(i)>='A'&&s.charAt(i)<='Z'){    // 65-90
                big++;
            }
            if (s.charAt(i)>='0'&&s.charAt(i)<='9'){    //48-57
                shuzi++;
            }
        }
        System.out.println(big);
        System.out.println(small);
        System.out.println(shuzi);
    }
}

这道题的核心:不用写出字符对应的asci码 直接用‘字符’来表示

八次求和

题目描述:

思路:

这个题想不出来可以混分,至少n属于(1-x)的情况是可以计算出来的 代码形式 if(n等于1)return x; if(n==2)return x;....

em…感觉这题有点歧义 因为没打括号

题解一:公式法

import java.math.BigInteger;
import java.util.Scanner;

public class sumForEight {
/*八次方求和*/
    static long MOD = 123456789;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        System.out.println(get(n));


    }
    static BigInteger get(int m) {
        //以下为公式:
        //(1^8+2^8+3^8+...+n^8) = (10n^9+45n^8+60n^7-42n^5+20n^3-3n)/90
        BigInteger n = BigInteger.valueOf(m); //记住api
        BigInteger result = BigInteger.ZERO;
        result = result.add(BigInteger.valueOf(10L).multiply(n.pow(9)));//记住api n.pow(9)表示n的9次方
        result = result.add(BigInteger.valueOf(45L).multiply(n.pow(8)));
        result = result.add(BigInteger.valueOf(60L).multiply(n.pow(7)));
        result = result.subtract(BigInteger.valueOf(42L).multiply(n.pow(5)));//记住减法api
        result = result.add(BigInteger.valueOf(20L).multiply(n.pow(3)));
        result = result.subtract(BigInteger.valueOf(3L).multiply(n));
        result = result.divide(BigInteger.valueOf(90L)); //记住除法api
        result = result.mod(BigInteger.valueOf(123456789L));
        return result;
    }
}

题解二:熟练使用BigInteger各种方法

import java.io.*;
import java.math.BigInteger;
import java.util.Scanner;

/*八次方求和*/
public class sumForEigth2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            BigInteger Bigmod = BigInteger.valueOf(123456789);
            BigInteger Bigsum = BigInteger.valueOf(0);
            int n=sc.nextInt();
            for(int i=1;i<=n;i++){
                BigInteger c =  BigInteger.valueOf(i);
                Bigsum=Bigsum.add(c.multiply(c).multiply(c).multiply(c).multiply(c)
                        .multiply(c).multiply(c).multiply(c));
            }
            BigInteger sum = Bigsum.mod(Bigmod);
            System.out.println(sum);
        }
    }

字符串编码(ac)

题目描述:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class StringEncord {
    /*123242526-->LCXYZ*/
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            char[] word = new char[27];          //将26个字母存储起来
            for(int i=1;i<word.length;i++){
                word[i]=(char)('A'+i-1);//注意点 char本身也需要加()
            }
            List<Character> list = new ArrayList<>();
            String s = sc.nextLine();
            int n = s.length();
            for (int i=0;i<n;){
                char c = s.charAt(i);
                if (c>='3'){
                    String s1 = c + "";
                    list.add(word[Integer.valueOf(s1)]);
                    i++;
                }else if (c=='2'&&(i+1)<n&&s.charAt(i+1)<='6'){
                    char c1 = s.charAt(i+1);
                    String s1 = c + ""+c1;
                    list.add(word[Integer.valueOf(s1)]);
                    i=i+2;
                }else if (c=='1'&&(i+1)<n){
                    char c1 = s.charAt(i+1);
                    String s1 = c + ""+c1;
                    list.add(word[Integer.valueOf(s1)]);
                    i=i+2;
                }else {
                    String s1 = c + "";
                    list.add(word[Integer.valueOf(s1)]);
                    i++;
                }
            }
            System.out.println(list);
        }
    }

    /*
     * ABCDEFGHIJKLMNOPQRSTUVWXYZ
     */

BST 插入节点问题

题目描述

题解:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class BST {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int[] parent = new int[n];
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int i = 0; i < n; i++) {
            parent[i] = sc.nextInt();
            map.put(i+1, sc.nextInt());
        }
        ArrayList<Integer> childs = new ArrayList<Integer>();
        int rootWeight = map.get(1);
        int kWeight = map.get(k);
        for(int i = 0; i < parent.length; i++) {
            if(k == parent[i]) childs.add(map.get(i+1));
        }
        // 1.parents不存在的节点就是叶子节点,叶子节点的答案是无穷大
        if(childs.size() == 0) {
            System.out.println("叶子节点");
            System.out.println(-1);
            return;
        }
        // 2. 已经有左右孩子,答案是0
        else if(childs.size() == 2) {
            System.out.println("已经有左右孩子了");
            System.out.println(0);
            return;
        }
        // 3. 在右子树:k节点有左无右时为-1;在左子树:k几点有右无左为-1
        else if(childs.size() == 1 && (kWeight > rootWeight && childs.get(0) < kWeight) || (kWeight < rootWeight && childs.get(0) > kWeight)) {
            System.out.println(-1);
            return;
        }
        else {
            int fatherWeight = map.get(parent[k-1]);
            System.out.println(Math.abs(kWeight-fatherWeight)-1);
            return;
        }
    }

}

网络分析(还没写)

2018蓝桥杯

复数幂(以小推大思维没有被建立起来)

题目描述

解题思路:

因为123456的幂次方,所以是一个大数,大数问题选择BigInteger和BigDecial(专门用来解决大数问题,前者用来解决大数整数,后置用来解决大数浮点数)

package 复数幂;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.math.BigInteger;

public class Main {
    public static void main(String[] args) throws FileNotFoundException {
        BigInteger c = BigInteger.valueOf(2);
        BigInteger d = BigInteger.valueOf(3);
        BigInteger a = BigInteger.valueOf(2);
        BigInteger b = BigInteger.valueOf(3);
        //(a+bi)*(c+di) = (a*c - b*d) + (a*d + b*c)i
        for(int i=1;i<2;i++) {
            BigInteger A = a.multiply(c).subtract(b.multiply(d));//实部
            BigInteger B = a.multiply(d).add(b.multiply(c));//虚部
            a=A;//如果不设置临时变量,后面b的值会出错
            b=B;
        }

            System.out.println(a.toString()+"+"+b.toString()+"i");
        }else {
            System.out.println(a.toString()+b.toString()+"i");
        }

    /*    System.out.println(a.toString()+b.toString()+"i");*/
    }

}

递增三元组(菜鸡多想想暴力)

题目描述:

蓝桥杯 - 图1

蓝桥杯 - 图2

蓝桥杯 - 图3

题解:

反思一下:刚开始看这题的时候居然没想到用暴力for来解决,可能是写了太多不用暴力解决的题目,思维被固化了。蓝桥杯比赛的时候,看完题目记得优先往暴力for上靠,不要管时间空间复杂度,能通过多少用例拿多少分。

暴力题解: 只有75分

package 递增三元组;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int count=0;  //用来计数
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();//每个数组的个数
        int a[]=new int[n];
        int b[]=new int[n];
        int c[]=new int[n];
        //初始化每个数组的值
        for (int i=0;i<n;i++){
            a[i]=scanner.nextInt();
        }
        for (int i=0;i<n;i++){
            b[i]=scanner.nextInt();
        }
        for (int i=0;i<n;i++){
            c[i]=scanner.nextInt();
        }
        //暴力法 三层for来解决  计数
        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                if (a[i]>=b[j]){
                    continue;
                }
                for (int z=0;z<n;z++){
                    if (a[i]<b[j]&&b[j]<c[z]){
                        count++;
                    }
                }
            }
        }
        System.out.println(count);
    }
}

优化: 只有87分

package 递增三元组;

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        long count=0;  //用来计数  要设置成long的 因为count可能很大
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();//每个数组的个数
        int a[]=new int[n];
        int b[]=new int[n];
        int c[]=new int[n];
        //初始化每个数组的值
        for (int i=0;i<n;i++){
            a[i]=scanner.nextInt();
        }
        for (int i=0;i<n;i++){
            b[i]=scanner.nextInt();
        }
        for (int i=0;i<n;i++){
            c[i]=scanner.nextInt();
        }
        Arrays.sort(a);
        Arrays.sort(b);
        Arrays.sort(c);
        int p=0;
        int q=0;
        for (int i=0;i<n;i++){
            while (p<n&&a[p]<b[i])p++;
            while (q<n&&c[q]<=b[i])q++;
            count=count+p*(n-q);
        }
        System.out.println(count);
    }
}

螺旋折线:

题目描述:

蓝桥杯 - 图4

蓝桥杯 - 图5

解题思路:做一条对角线,利用等差队列来算

package 螺旋折线;

import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main {
    // 以 右下角 对角线上的点 为 参照点,测算给定的点到参照点要走的距离

    public static void main(String[] args) throws FileNotFoundException {
        Scanner sc = new Scanner(System.in);
        long X = sc.nextLong(), Y = sc.nextLong();
        long d = 0; // 距离  举例最右下角的距离
        long n = 0; // 第几圈

        if (Y > 0 && Math.abs(X) <= Y) { // 点在上面的横线上
            n = Y; // 等差数列有多少项? Y项
            d = (Y - X) + (2 * Y); // X的最大值是Y,第一、四象限的距离---2Y
        } else if (X > 0 && Math.abs(Y) <= X) { // 点在最右边的横线上
            n = X;
            d = Y + X;
        } else if (Y <= 0 && X >= Y - 1 && X <= -Y) { // 点在最下边的横线上
            n = -Y; //2
            d = -(-Y - X);//-4
        } else if (X < 0 && Y >= X + 1 && Y <= -X) { // 点在最左边的横线上
            n = -X - 1;
            d = -(Y - X - 1 - 2 * X - 1);
        }

        System.out.println(sum(2, 2 * n, 2) - d);

    }

    /**
     * 等差数列求和
     *
     * @param a0 首项
     * @param n  项数
     * @param d  公差
     * @return
     */
    private static long sum(long a0, long n, int d) {
      return n*a0+d*n*(n-1)/2;
    }

}

2017蓝桥杯

1.购物单(ac)

解法:excel或者计算器

2.纸牌三角形(蛮难的)

题目描述:

蓝桥杯 - 图6

思路:全排列

代码:

public class Solution {
    static int count = 0;

    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        dfs(arr, 0);
        System.out.println(count / 6);
    }

    // 全排列
    public static void dfs(int[] arr, int index) {
        if (index == arr.length) {
            // 已经够成一个了
            int col = arr[0] + arr[1] + arr[3] + arr[5];
            int row = arr[5] + arr[6] + arr[7] + arr[8];
            int xie = arr[0] + arr[2] + arr[4] + arr[8];
            if (col > 0 && col == row && row == xie) {
                count++;
            }
            return;
        }
        for (int i = index; i < arr.length; i++) {
            swap(arr, index, i);
            dfs(arr, index + 1);
            swap(arr, index, i);
        }
    }

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

3.承重计数(半ac。拿不到分,但是可以拿到分)

题目描述

蓝桥杯 - 图7

蓝桥杯 - 图8

蓝桥杯 - 图9

package 承压计算;

import java.util.Scanner;

public class Main {
   public static void main(String[] args) {
      Scanner scanner = new Scanner(System.in);
      //30行30列的数组
      double a[][]=new double [30][30];
      //如果上面定义的数组类型为Double 不显示初始化的因为是引用类型 不赋值就是null 不是0了 而double就是0.0
   // System.out.println(a[29][29]);
      for(int i=0;i<29;i++) {
         for(int j=0;j<=i;j++) {
            a[i][j]=scanner.nextDouble();
         }
      }
      //为了让最后一行得到值 不为null
      /*for (int i=0;i<30;i++){
         a[29][i]=0.0;
      }*/
      //类似杨辉三角
      for(int i=1;i<=29;i++) {
         for(int j=0;j<=i;j++) {
            if(j==0) {
               a[i][j]=a[i-1][j]/2+a[i][j];
            }else if(j>0&&j<i) {
               a[i][j]=a[i-1][j-1]/2+a[i-1][j]/2+a[i][j];
            }else {
               a[i][j]=a[i-1][j-1]/2+a[i][j];
            }

         }
      }
      double max=0.0;
      double min=Double.MAX_VALUE;
      //遍历最后一层 去一个最大的即可
      for(int i=0;i<=29;i++) {
         if(a[29][i]>max) {
            max=a[29][i];
         }
         if(a[29][i]<min) {
            min=a[29][i];
         }

      }
      System.out.println(max);
      System.out.println(min);
      System.out.println((2086458231  * max)/ min);

   }

}

5.取数位(ac)

题目描述

蓝桥杯 - 图10

答案:f(x/10, k)

思路分析:

因为是补全代码,所以就大胆试嘛,示例中给的例子是x=23513,但这题无论x等于什么,貌似影响不太大。因此我们取x=13,k=1或者2来调试。这样一试,马上就能猜到答案了。再让x取一些较大的数和不同的k,发现都满足。因此答案就是f(x/10, k)

6.最长公共子串(ac)

7.日期问题(感觉写的出来,但是看了答案。该死)

题目描述

蓝桥杯 - 图11

思路分析以及对api的分析

编码:

package quanpailie;

import java.util.Scanner;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.TreeSet;


public class Main {
     public static HashSet<Integer>  set = new HashSet<Integer>();   //去重
        public static List<Integer> list =new ArrayList<Integer>();  
        public static void f(String year,String mon,String day)  
        {  
            int y = Integer.parseInt(year);   //记住这个 0x会变成x
            int m = Integer.parseInt(mon);  
            int d = Integer.parseInt(day);  
            if(y<=59)  
            {  
                y+=2000;  
            }else {  
                y+=1900;  
            }  
            //如果是闰年 2月
           if(y/4==0&&m==2&&d<=29) {
               set.add(Integer.parseInt(""+y+mon+day));
           }
           //平年二月
           if(y/4!=0&&m==2&&d<=28) {
               set.add(Integer.parseInt(""+y+mon+day));
           }
           //大月
           if((m==1||m==3||m==5||m==7||m==8||m==10||m==12)&&d<=31) {
               set.add(Integer.parseInt(""+y+mon+day));
           }
           //小月
           if((m==4||m==6||m==9||m==11)&&d<=30) {
               set.add(Integer.parseInt(""+y+mon+day));
           }

        }  
    public static void main(String[] args) {  
        Scanner in = new Scanner(System.in);  
        String str = in.nextLine();  
        String[] s =str.split("/");  
        f(s[0],s[1],s[2]);  
        f(s[2],s[0],s[1]);  
        f(s[2],s[1],s[0]);  
        list.addAll(set);  
        for(int i=0;i<list.size();i++)  
        {  
            String ans = ""+list.get(i);  
            System.out.println(ans.substring(0, 4)+"-"+ans.substring(4,6)+"-"+ans.substring(6,8));  
        }  

    } 

}

8.包子凑数(dp问题,不太好想)

题目描述:

蓝桥杯 - 图12

蓝桥杯 - 图13

思路分析

先从他给的案例分析,分别是【4,5】和【4,6】,【4,6】的话一定拼不出来基数,因此有无穷个,同理都为偶数也肯定是无穷个。

蓝桥杯 - 图14

package 包子凑数;
import java.util.Scanner;

public class 蓝桥杯_包子凑数 {

   public static void main(String[] args) {
      Scanner sc = new Scanner(System.in);
      int n = sc.nextInt();
      int g=0;
      boolean []dp=new boolean[10000];
      dp[0]=true;
      int[] a = new int[101];//因为n为[1-100]   


      for(int i=1;i<=n;i++) {    
         a[i] = sc.nextInt();
      // 求所有ai的最大公约数
      if(g==1) {
         g=a[i];
      }else {
         g=gcd(a[i],g);
      }
      for(int j=0;j<10000-a[i];j++) {//貌似等于也不影响
         if(dp[j]==true) {
            dp[a[i]+j]=true;
         }
      }
      }
      if(g!=1) { //奇奇 偶偶都会使得g=1 都是无穷
         System.out.println("INF");
         return;
      }
      int num=0;
      for(int i=0;i<10000;i++) {
         if(dp[i]!=true) {
            num++;
         }

      }
      System.out.println(num);

   }
   //判断最大公约数
   static int gcd(int a,int b) {
      return b==0?a:gcd(b,a%b);
   }

}

9.分巧克力(二分写不出来)

题目描述:

蓝桥杯 - 图15

蓝桥杯 - 图16

思路分析:

解法一暴力法(推荐)

package 分巧克力;


import java.util.Scanner;
//代码提交题 没有思路优先想暴力 没有暴力思路先跳 去看后面的  (暴力都写不出来那就没办法咯)
class Main{
    public static void main(String[] args) {
        int n, k;
        int[] h = new int[100000];
        int[] w = new int[100000];
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        k = sc.nextInt();
        for (int i = 0; i < n; ++i) {
            h[i] = sc.nextInt();
            w[i] = sc.nextInt();
        }
        int len =100000;
        int count=0;
        //记录边长
        int bian=0;
        for (;len>0;len--){
            count=0;
            //每个巧克力块,都按照len来切割
            for (int i = 0; i < n; ++i) {
                count += (h[i] / len) * (w[i] / len);
            }
            if (count>=k){
                bian=len;
                break;
            }
        }
        System.out.println(bian);

    }



}

解法二:二分优化法

package 分巧克力;


import java.util.Scanner;
//代码提交题 没有思路优先想暴力 没有暴力思路先跳 去看后面的  (暴力都写不出来那就没办法咯)
class Main{
    public static void main(String[] args) {
        int n, k;
        int[] h = new int[100000];
        int[] w = new int[100000];
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        k = sc.nextInt();
        for (int i = 0; i < n; ++i) {
            h[i] = sc.nextInt();
            w[i] = sc.nextInt();
        }

        int r = 100001;
        int l = 1;
        int ans = 0;
        while (l <= r) {
            int mid = (l + r) / 2;

            int cnt = 0;
            //每个巧克力块,都按照len来切割
            for (int i = 0; i < n; ++i) {
                cnt += (h[i] / mid) * (w[i] / mid);
            }

            if (cnt >= k) {
                l = mid + 1;
                ans = mid;
            } else {
                r = mid - 1;
            }
        }
        System.out.println(ans);
    }
}

10.k倍区间(暴力思维建立起来了不错不错)

题目描述

蓝桥杯 - 图17

蓝桥杯 - 图18

思路:暴力,写完测试案例,除了案例外 再多测两个 防止偶然性代码白写不得分 拿了28分

package k倍区间;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int k = scanner.nextInt();
        int []nums=new int[n+1];
        long count=0;
        long sum=0;
        for(int i=1;i<=n;i++){
            nums[i] = scanner.nextInt();
        }
        //暴力for
        for(int i=1;i<=n;i++) {
            for(int j=i;j<=n;j++) {
                if(i==j&&nums[i]%k==0) {
                    count++;
                }else if(i==j&&nums[i]%k!=0){
                }
                else {
                    int s=i;
                    while(s<=j) {
                        sum+=nums[s] ;
                        s++;
                    }
                    if(sum%k==0) {
                        count++;

                    }sum=0;
                }
            }
        }System.out.println(count);

    }

}

思路二:前缀和 通过率还是28分

import java.util.Scanner;

public class _10k倍区间 {

   /**
    * @param args
    */
   public static void main(String[] args) {
      // TODO Auto-generated method stub
      Scanner input = new Scanner(System.in);
      int n = input.nextInt();
      int k = input.nextInt();
      int[] a = new int[n+1];
      //前缀和数组
      int qian []=new int[n+1];

      for(int i=1;i<=n;i++){
         a[i] = input.nextInt();
         qian[i]=qian[i-1]+a[i];
      }

      int count = 0;
      for(int i=1;i<=n;i++){
         for(int j=i;j<=n;j++){
            if((qian[j]-qian[i-1])%k==0)
               count++;
         }
      }

      System.out.println(count);
   }

}

2021蓝桥杯

8.杨辉三角形

题目描述:

蓝桥杯 - 图19

蓝桥杯 - 图20

不要写成dp[10000][10000],因为超出内存限制了,一个测试用例都过不了的

思路:用个二维数组将杨辉三角的所有值按顺序装进去 于是乎写出下面的代码 下面的代码只能拿30 改成dp[7000][7000](230的内存)能拿40(改成100也能拿40分,占用内存23),具体暴力多少适当就好,不要太大否则容易gg

package 杨辉三角形;

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
      Scanner scanner = new Scanner(System.in);
      int n = scanner.nextInt();
      //存数据
      int dp[][]=new int[60][60];
      dp[0][0]=1;
      dp[1][0]=1;
      dp[1][1]=1;
      int count=0;
      //行
      for(int i=2;i<60;i++) {
         //列
         for(int j=0;j<=i;j++) {
            if(j==0) {
               dp[i][j]=dp[i-1][j];
            }else if(j==i) {
               dp[i][j]=dp[i-1][j-1];
            }else {
               dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
            }
         }
      }
      //遍历找值
      for(int i=0;i<60;i++) {
         for(int j=0;j<=i;j++) {
            if(dp[i][j]==n) {
               System.out.println(count+1);
               return;
            }else {
               count++;
            }
         }
      }
}
}

满分题解(想不出来)

package 杨辉三角形;

import java.util.Scanner;
/*杨辉三角形满分题解*/
public class Main100 {
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
            long n = scan.nextLong();//输入值,查找
            long[] arr =new long[44722];
            arr[0]=1;
            long k=1L;//k来定义位置
            if (n == 1) {
                System.out.println(1);
                return;
            }

            for (int i = 1;i<447225; i++) {
                for (int j = i; j>=1; j--) {
                    arr[j] += arr[j - 1];//换行后,用自己进行运算,减少内存
                    if (arr[j] == n) {
                        System.out.println(k + i-j + 1);
                        return;//如果找到了就结束
                    }
                }
                k+=(i+1);
            }
            System.out.println(((1 + n) * n / 2) + 2);
        }
    }

4.货物摆放(看答案的自己没写出来)

题目描述:

蓝桥杯 - 图21

蓝桥杯 - 图22

思路:

求约数,组成的L、W、H必然是n的约数,我们把n的约数全求出来,然后暴力三层for来组合,如若等于n,则+1。

细节点:n有16位数,int最多10位,long有19位,因此选择用long来存储。

package 货物摆放;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
   public static void main(String[] args) {
      long n=2021041820210418L;
      //求出所有约数
      List<Long> list=new ArrayList<Long>();
      for(long i=1;(i*i)<=n;i++) {
         if(n%i==0) {
            list.add(i);
            if(n/i!=i) {
               list.add(n/i);
            }
         }
      }
      System.out.println(list);
      int count=0;
      //遍历
      for(int a=0;a<list.size();a++) {
         for(int b=0;b<list.size();b++) {
            for(int c=0;c<list.size();c++) {
               if(list.get(a )*list.get(b)*list.get(c)==n) {
                  count++;
               }
            }
         }
      }
      System.out.println(count);}
}

6.时间显示

问题描述:

蓝桥杯 - 图23

蓝桥杯 - 图24

思路:

因为ms数不超过10的18次方,因此可以用long来存储,由于不记录ms数,我们可以通过/1000将ms删去。

package 时间显示;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class Main {
   public static void main(String[] args) throws ParseException {
       Scanner scanner = new Scanner(System.in);
       long tt = scanner.nextLong();
       //将毫秒转为秒 因为ms可以不显示
       tt/=1000;
       long ss=tt%60;
       tt=tt/60;
       long mm=tt%60;
       tt/=60;
       long hh=tt%24;
       //数字格式化输出   记下来
       System.out.println(String.format("%02d", hh)+":"+String.format("%02d", mm)+":"+String.format("%02d", ss)); S
   }
}

7.最少砝码(算法题,找规律也很重要,数感也很重要)

题目描述:

蓝桥杯 - 图25

蓝桥杯 - 图26

思路:选大不选小 最后发现都得是3的倍数

(7条消息) 第十二届蓝桥杯省赛JavaB组 试题 G: 最少砝码小小风0的博客-CSDN博客最少砝码java

package 最少砝码;

import java.util.Scanner;

public class Main {
   public static void main(String[] args) {
   Scanner scanner = new Scanner(System.in);
   int n = scanner.nextInt();
   int count=0;
   int sum=0;
   while(sum<n) {
      sum+=Math.pow(3, count);
      count++;
   }
   System.out.println(count);
}
}

9.双向排序(拿了60分)

题目描述:

蓝桥杯 - 图27

蓝桥杯 - 图28

蓝桥杯 - 图29

思路:暴力骗分 不要看是第九题就怕 能拿多少分拿多少分

代码:

package 双向排序;

import java.util.Arrays;
import java.util.Scanner;

public class Main {

   public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);

       //接收序列的长度和操作次数
       int length = sc.nextInt();
       int count  = sc.nextInt();
       int end=length-1;
       //初始化序列
       int[] arr = new int[length];
       for(int i = 0; i < arr.length; i++) {
          arr[i] = i+1;
       }
       for(int i=0;i<count;i++) {
          int p=sc.nextInt();
          int index=sc.nextInt();
          //如果是升序
          if(p==1) {
             //对0到index进行升序  有直接api 舒服啊啊啊啊  被坑了:这玩意左闭右开
             Arrays.sort(arr,index-1,length);
            /*
             * for(int b=0;b<length;b++) { System.out.println(arr[b]); }
             */
          }else {
             int s=index-1;
             //对index-length进行降序
             //这步很关键
             Arrays.sort(arr,0,index);
             for(int j=0;j<=(index-1)/2;j++) {
               int temp= arr[j];
               arr[j]=arr[s];
               arr[s]=temp;
               s--;
             }
            /*
             * for(int x=0;x<length;x++) { System.out.println(arr[x]); }
             */

          }
       }
//注意细节点 第一遍的时候,可是用了换行符喔 并且""里面忘记加了空格
       for(int i=0;i<length;i++) {
          System.out.print(arr[i]+" ");
       }




   }

}