当前位置: 首页 > article >正文

「蓝桥杯题解」数字接龙

前言

这个是我的 ac 代码,里面的注释是用自己的话写的。因为我看蓝桥杯官方题解文字和代码分离,代码部分没有注释,看着巨难受,所以自己写了一版。感觉他们的视频解析也挺水的(小声

题目链接

代码

import java.util.*;

/**
 * 数字接龙
 */

public class Main {
    static Scanner in = new Scanner(System.in);
    static int n,k;
    static final int N = 11;
    static int[][] board = new int[N][N];
    static boolean[][] vis = new boolean[N][N];
    // 8*2 向量数组,其中下标 1 3 5 7 为对角线方向
    static int[][] d = {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};

    static boolean[][][][] line = new boolean[N][N][N][N]; // 用来判断 (x1,y1) 是否可以沿对角线方向走到 (x2,y2)

    static void dfs(int x1,int y1,ArrayList<Integer> path) {
        // 终止条件:到右下角的那个格子
        if (x1 == n-1 && y1 == n-1) {
            // 没有把所有格子走完,不符题意
            if (path.size() != n*n - 1) return;
            // 输出路径
            for(int x : path) {
                System.out.print(x);
            }
            System.exit(0);
        }
        
        // 调试用的:System.out.println("(x1,y1): " + x1 + "," +y1);
        // ps:vis[x1][y1] = true;  加了这句就可以不用专门写 vis[0][0] = true
        // ps:因为我们是按 i 从小到大枚举的,所以如果存在答案,那么最先找到的那条路径肯定是字典序最小的
        for (int i = 0; i < 8; i++) {
            int x2 = x1 + d[i][0],y2 = y1 + d[i][1];
            // 判断边界以及是否访问过
            if (x2 < 0 || x2 >= n || y2 < 0 || y2 >= n || vis[x2][y2]) continue;
            // 判断大小
            if ((board[x1][y1] + 1) % k != board[x2][y2] || line[x1][y1][x2][y2]) continue;

            // 沿对角线方向走,判断是否会交叉,这里四种情况(四个方向)只能分别老老实实写出来
            if(i == 1 && (line[x1 - 1][y1][x1][y1 + 1] || line[x1][y1 + 1][x1 - 1][y1])) continue ;
            if(i == 3 && (line[x1][y1 + 1][x1 + 1][y1] || line[x1 + 1][y1][x1][y1 + 1])) continue ;
            if(i == 5 && (line[x1][y1 - 1][x1 + 1][y1] || line[x1 + 1][y1][x1][y1 - 1])) continue ;
            if(i == 7 && (line[x1 - 1][y1][x1][y1 - 1] || line[x1][y1 - 1][x1 - 1][y1])) continue ;

            path.add(i);
            vis[x2][y2] = true;
            if (i % 2 == 1) line[x1][y1][x2][y2] = true;
            dfs(x2,y2,path);
            // 回溯
            path.remove(path.size()-1);
            vis[x2][y2] = false;
            if (i % 2 == 1) line[x1][y1][x2][y2] = false;
        }
    }

    public static void main(String[] args) {
        n = in.nextInt(); k = in.nextInt();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                board[i][j] = in.nextInt();
            }
        }
        vis[0][0] = true;
        dfs(0,0,new ArrayList<>());
        System.out.println(-1);
    }
}


http://www.kler.cn/a/504876.html

相关文章:

  • 易语言文字识别OCR
  • 计算机的错误计算(二百一十二)
  • Linux 服务器挖矿木马防护实战:快速切断、清理与加固20250114
  • 计算机网络之---应用层协议概述
  • golang运维开发-gopsutil(1)
  • 【gin】http方法了解,以及RESTful API与版本控制
  • 石化煤矿智能化转型“硬通货”,遨游防爆手机如何面面俱到?
  • Vue2+OpenLayers实现车辆开始、暂停、重置行驶轨迹动画(提供Gitee源码)
  • UART 串口的全双工模式与 SPI 的全双工模式的区别
  • 达梦数据库数据迁移(mysql迁移到达梦)
  • 4种革新性AI Agent工作流设计模式全解析
  • 力扣cf补题-1【算法学习day.94】
  • 字符串提取数字求和⭐
  • Spring Boot 应用开发中的核心注解及扩展(包含自动配置源码追踪)
  • 2025.1.15——二、字符型注入
  • STM32 物联网智能家居 (三) 输入子系统
  • 语言月赛 202407【significance】题解(AC)
  • Web_HTML+CSS_First_Asignment
  • C#对动态加载的DLL进行依赖注入,并对DLL注入服务
  • 前端组件开发:组件开发 / 定义配置 / 配置驱动开发 / 爬虫配置 / 组件V2.0 / form表单 / table表单
  • linux 端口转发工具rinetd
  • Flask安全开发
  • 亚洲科技创新之夜即将闪耀CES Asia 2025首日
  • 网络安全测评质量管理与标准解读
  • Tmux复制时将内容传递到系统剪贴板
  • vue2 web 多标签输入框 elinput是否当前焦点