AcWing蓝桥杯总结Day02

97 阅读2分钟

递推

例题

AcWing717. 简单斐波那契 (递推实现)

import java.util.*;

public class Main{
    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int[] dp = new int[N];
        
        System.out.print(0 + " ");
        if(N != 1) {
            dp[1] = 1;
            System.out.print(1 + " ");
            
            for(int i = 2; i < N; ++i){
                dp[i] = dp[i-1] + dp[i-2];
                System.out.print(dp[i] + " ");
            }
        }
        
    }
}

AcWing95 费解的开关

import java.util.*;

public class Main {

    static boolean[][] backup = new boolean[5][5];

    static boolean[][] board = new boolean[5][5];

    static int[][] dir = new int[][] { {1,0}, {0, 1}, {0, -1}, {-1, 0}};

    static void turn(int x, int y) {
        backup[x][y] = !backup[x][y];

        for(int i = 0; i < dir.length; i++) {
            int nextX = x + dir[i][0];
            int nextY = y + dir[i][1];
            if(nextX < 0 || nextX >= 5 || nextY < 0 || nextY >= 5) continue;
            backup[nextX][nextY] = !backup[nextX][nextY];
        }
    }


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

        
        
        for (int i = 0; i < n; ++i) {

            int minSteps = Integer.MAX_VALUE;
            
            //初始化状态
            for (int x = 0; x < 5; ++x) {
                String s = sc.nextLine();
                for (int y = 0; y < 5; ++y) {
                    board[x][y] = s.charAt(y) == '1';
                }
            }



            // 枚举对第一行的所有操作
            for (int op = 0; op < 32; ++op) {
                //状态备份
                for (int x = 0; x < 5; ++x) {
                    System.arraycopy(board[x], 0, backup[x], 0, 5);
                }


            
                int usedSteps = 0;
                

                //对第一行操作
                for (int j = 0; j < 5; j++) {
                    if ((op >> j & 1) == 1) {
                        turn(0, j);
                        usedSteps++;
                    }
                }

                for (int x = 1; x < 5; ++x) {
                    for (int y = 0; y < 5; ++y) {
                        if (!backup[x - 1][y]) {
                            turn(x, y);
                            usedSteps++;
                        }
                    }
                }

                boolean dark = false;
                for (int y = 0; y < 5; ++y) {
                    if (!backup[4][y]) {
                        dark = true;
                        break;
                    }
                }

                if (usedSteps <= 6 && !dark) {
                    minSteps = Math.min(minSteps, usedSteps);
                }
                
            }

            System.out.println(minSteps == Integer.MAX_VALUE ? -1 : minSteps);
            if(sc.hasNextLine()) sc.nextLine();
        }
    }
}

习题

AcWing116. 飞行员兄弟

import java.util.Scanner;

public class AcWing116 {

    static int state = 0;

    static int backupState = 0;

    // 执行翻转操作的函数
    static void turn(int n) {
        int row = (15 - n) / 4;  // 行号
        int col = (15 - n) % 4;  // 列号

        // 翻转当前位置
        backupState ^= (1 << n);

        // 翻转同行
        for (int i = 0; i < 4; i++) {
            if (i != col) {
                backupState ^= (1 << (15 - (row * 4 + i))); // 翻转同一行
            }
        }

        // 翻转同列
        for (int i = 0; i < 4; i++) {
            if (i != row) {
                backupState ^= (1 << (15 - (i * 4 + col)));  // 翻转同一列
            }
        }
    }


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

        //初始化状态
        for(int i = 0; i < 4; ++i){
            String s = sc.nextLine();
            for(int j = 0; j < 4; ++j){
                int bit = s.charAt(j) == '-' ? 0 : 1;
                state = (state << 1) + bit;
            }
        }

        int minStep = Integer.MAX_VALUE;

        int minOp = -1;

        for(int op = (1<<16)-1; op >= 1; --op){
            backupState = state;

            int steps = 0;
            for(int j = 15; j >= 0; --j){
                int bit = op >> j & 1;
                if(bit == 1){
                    turn(j);
                    ++steps;
                }
            }

            boolean flag = true;
            for(int i = 0; i < 16; ++i){
                if((backupState >> i & 1) == 1){
                    flag = false;
                    break;
                }
            }

            if(flag && steps < minStep){
                minOp = op;
                minStep = steps;
            }
        }

        System.out.println(minStep);
        // 如果有可行的解,输出具体的操作
        if (minOp != -1) {
            for (int i = 15; i >= 0; --i) {
                int bit = minOp >> i & 1;
                if (bit == 1) {
                    int row = (15 - i) / 4 + 1;
                    int col = (15 - i) % 4 + 1;
                    System.out.println(row + " " + col);  // 输出操作位置
                }
            }
        }
    }
}

AcWing1208.翻硬币

import java.util.*;

public class Main{
    
    static char[] initialArr;
    static char[] targetArr;


    static void flip(int i){
        flip0(i);
        flip0(i+1);
    }

    private static void flip0(int i){
        if(initialArr[i] == '*') initialArr[i] = 'o';
        else initialArr[i] = '*';
    }

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

        String initialStr = sc.nextLine();
        String targetStr = sc.nextLine();

        int n = initialStr.length();


        initialArr = initialStr.toCharArray();
        targetArr = targetStr.toCharArray();

        int steps = 0;
        for(int i = 0; i < n - 1; ++i){
            if(initialArr[i] != targetArr[i]) {
                flip(i);
                ++steps;
            }
        }

        System.out.println(steps);
    }
}