十三届蓝桥杯javaB组拉箱子

有没有大神能够告诉我这道压轴题有什么更快的做法,本以为数据不大深搜加剪枝能过的,只能向网上的acm帅哥求真经了。

最后一个案例没有过去,但是有人用了200ms的做法过了,我实在想不出有什么更快的方法了,感觉这题用动态规划可变参数会特别麻烦应该不是最优做法吧(我猜的)。

先附上我超时的代码:算是记录一下。

​
import java.util.HashSet;
import java.util.Scanner;
public class Main {
    static int ans = 0;
    static int[][] arr;
    static int len1;
    static int len2;
    static Scanner scan = new Scanner(System.in);
    public static void main(String[] args) {
        way1();
    }
    public static void way1(){
        int n = scan.nextInt(),m = scan.nextInt();
        arr = new int[n][m];
        len1 = n;len2 = m;
        f1 = new boolean[n][m][n][m];
        HashSet<Integer> s = new HashSet<>();
        for(int i = 0;i < n;i++){
            for(int j = 0;j < m;j++){
                arr[i][j] = scan.nextInt();
            }
        }
        dfs(0,0,s);
        System.out.println(ans);
    }

    static int[][] index = new int[5][2];
    public static void dfs(int row, int col, HashSet<Integer> s){
        if(row == arr.length){
            if(s.size() == 3){
                if(check(index[2][0],index[2][1],index[3][0],index[3][1])){
                    ans++;
                }
            }
        }else{
            if(arr[row][col] == 1){
                if(col == len2 - 1){
                    dfs(row+1,0,s);
                }else{
                    dfs(row,col+1,s);
                }
            }else if(s.size() == 3){
                arr[row][col] = 5;
                if (col == len2 - 1) {
                    dfs(row + 1, 0, s);
                } else {
                    dfs(row, col + 1, s);
                }
                arr[row][col] = 0;
            } else{
                for(int i = 2;i <= 4;i++) {
                    if (!s.contains(i)) {
                        arr[row][col] = i;
                        s.add(i);
                        index[i][0] = row;
                        index[i][1] = col;
                        if (col == len2 - 1) {
                            dfs(row + 1, 0, s);
                        } else {
                            dfs(row, col + 1, s);
                        }
                        s.remove(i);
                    }
                }
                arr[row][col] = 5;
                if (col == len2 - 1) {
                    dfs(row + 1, 0, s);
                } else {
                    dfs(row, col + 1, s);
                }
                arr[row][col] = 0;
            }
        }
    }
    static int[][] dir = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
    static boolean[][][][] f1;
    public static boolean check(int row2,int col2,int row3,int col3){
        if(row3 == index[4][0] && col3 == index[4][1]){
            return true;
        }
        f1[row2][col2][row3][col3] = true;
        for(int[] d:dir){
            int r = row2 + d[0];
            int c = col2 + d[1];
            boolean flag = row2 - d[0] == row3 && col2 - d[1] == col3;
            if(R(r,c,row3,col3)){
                if(check(r,c,row3,col3)){
                    f1[row2][col2][row3][col3] = false;
                    return true;
                }
            }
            if(flag){
                if(R(r,c,row2,col2)){
                    if(check(r,c,row2,col2)){
                        f1[row2][col2][row3][col3] = false;
                        return true;
                    }
                }
            }
        }
        f1[row2][col2][row3][col3] = false;
        return false;
    }
    public static boolean R(int row,int col,int row1,int col1){
        return row >= 0 && row < len1 && col >= 0 && col < len2 && arr[row][col] != 1 &&
                !(row == row1 && col == col1) && !f1[row][col][row1][col1];
    }
}

​

最后诺诺的问一句:准备国赛是省赛,国赛题目双休好呢还是只做国赛题目好呢,就怕国赛题目连题解都找不到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值