首页 > 其他分享 >路径之谜(DFS)-2016年蓝桥杯国赛

路径之谜(DFS)-2016年蓝桥杯国赛

时间:2023-06-17 21:04:22浏览次数:36  
标签:杯国赛 DFS 蓝桥 int 箭靶 static new 骑士 public



路径之谜-2016年国赛

  • 1、题目描述
  • 2、解题思路
  • 3、代码实现


1、题目描述

  小明冒充 X 星球的骑士,进入了一个奇怪的城堡。

  城堡里边什么都没有,只有方形石头铺成的地面。

  假设城堡地面是 n×n* 个方格。如下图所示。

路径之谜(DFS)-2016年蓝桥杯国赛_数据结构

  按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有 n 个靶子)同一个方格只允许经过一次。但不必走完所有的方格。如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?有时是可以的,比如上图中的例子。

  本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)


输入描述

  第一行一个整数 N (0≤N≤20),表示地面有路径之谜(DFS)-2016年蓝桥杯国赛_深度优先_02个方格。

  第二行 N 个整数,空格分开,表示北边的箭靶上的数字(自西向东)

  第三行 N 个整数,空格分开,表示西边的箭靶上的数字(自北向南)


输出描述

  输出一行若干个整数,表示骑士路径。

  为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3 ⋯⋯

  比如,上图中的方块编号为:

0 1 2 3

4 5 6 7

8 9 10 11

12 13 14 15

输入输出样例

示例

输入

4
2 4 3 4
4 3 3 3

输出

0 4 5 1 2 3 7 11 10 9 13 14 15

运行限制

  • 最大运行时间:5s
  • 最大运行内存: 256M

2、解题思路

  看到这种给一个起点和终点走方格的时候,第一反应就应该是DFS或者BFS了,一条路走到黑这种适合DFS,这题很符合。

  骑士从左上角起点出发,没走一步,往左边和上边对应位置射一箭,题目在方格的左边和上边给出了骑士从起点到终点射箭的数量,现在让我们求骑士行走的路线。

  那我们可以逆向一下,我们从入口开始走,没走一步就将当前位置左边和上边箭的数量减一,如果我们走到了终点且当前所有箭靶上箭的数量为零,则说明我们所走的路线就是骑士经过的路线

  我们设置一个方向

路径之谜(DFS)-2016年蓝桥杯国赛_java_03

public static int[][] dirs = {
            {-1, 0},    //上
            {1, 0},     //下
            {0, -1},    //左
            {0,1}       //右
    };

  从起点开始DFS,没走一个新的位置,就要进行判断

  • 如果该点是终点,且箭靶上箭的数量为0,则说明走过的路线就是骑士经过的路线,算法结束。
  • 如果当前点不是终点,且没有被访问过,那么我们可以用一个path数组记录下该路径,然后继续向上下左右进行DFS。
  • 如果走到终点且箭靶上的箭还没有被拔完,那我们就要济宁回溯操作(标记当前点未访问,左边箭靶数量+1,上边箭靶数量+1)。

3、代码实现

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class Main {
    public static int n;
    public static int[] path;       //记录路径
    public static int[] countLeft;  //左边箭靶上的箭
    public static int[] countUp;    //上边箭靶上的箭
    public static boolean[][] visited;  //访问标记
    public static boolean success=false;//走到终点的标记
    public static int[][] dirs={
            {-1,0}, //上
            {1,0},  //下
            {0,-1}, //左
            {0,1}   //右
    };
    public static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    public static void main(String[] args) throws IOException {
        n=nextInt();
        countLeft=new int[n];
        countUp=new int[n];
        path=new int[n*n];
        visited=new boolean[n][n];
        for (int i = 0; i <n; i++) {
            countUp[i]=nextInt();
        }
        for (int i = 0; i <n ; i++) {
            countLeft[i]=nextInt();
        }
        //从起点开始dfs
        dfs(0,0,0);
    }

    public static void dfs(int x, int y, int step) {
        path[step]=x*n+y;   //将该点编号转变为一维并记录
        visited[x][y]=true; //访问标记
        countLeft[x]--; //拔掉左边箭靶上的箭
        countUp[y]--;   //拔掉右边箭靶上的箭
        if(x==n-1&&y==n-1&&check()){    //是否到达终点
            success=true;   //标记已经走到终点
            for (int i = 0; i <=step ; i++) {
                System.out.print(path[i]+" ");
            }
            return;
        }
        for (int[] dir : dirs) {    //四个方向搜索
            int tmpX=x+dir[0];
            int tmpY=y+dir[1];
            //没有到达终点且不越界,且(tmpX,tmpY)没有被访问过
            if(!success&&tmpX>=0&&tmpX<=n-1&&tmpY>=0&&tmpY<=n-1&&!visited[tmpX][tmpY]){
                dfs(tmpX,tmpY,step+1);  //搜索下一步
                visited[tmpX][tmpY]=false;  //复原,回溯
                countLeft[tmpX]++;
                countUp[tmpY]++;
            }
        }
    }

    public static boolean check() { //
        for (int i = 0; i < n; i++) {
            //到终点的时候箭还没有拔完
            if(countLeft[i]!=0||countUp[i]!=0){
                return false;
            }
        }
        //到终点时箭刚好拔完
        return true;
    }

    public static int nextInt() throws IOException{
        st.nextToken();
        return (int)st.nval;
    }
}

跑一个测试用例看看

路径之谜(DFS)-2016年蓝桥杯国赛_java_04

路径之谜(DFS)-2016年蓝桥杯国赛_数据结构_05数组中记录的是经过的每个方格的编号,最后将这些编号输出即为骑士从起点到终点走过的路径。


标签:杯国赛,DFS,蓝桥,int,箭靶,static,new,骑士,public
From: https://blog.51cto.com/u_15961549/6506207

相关文章

  • 十一届蓝桥杯研究生组国赛-循环小数(数论)
    十一届蓝桥杯研究生组国赛-循环小数1、题目描述2、解题思路3、代码实现1、题目描述  已知S是一个小于11的循环小数,请计算与S相等的最简真分数是多少。  例如0.3333⋯0.3333⋯等于1331,0.1666⋯0.1666⋯等于1661。输入描述  输入第一行包含两个整数p和q,表示......
  • 使用Node.js和WebHDFS REST API访问Hadoop HDFS数据
    可用服务以下是可用的服务集:1)文件和目录操作  1.1创建和写入文件:CREATE(HTTPPUT)  1.2附加到文件:APPEND(HTTPPOST)  1.3打开并读取文件:OPEN(HTTPGET)  1.4创建目录:MKDIRS(HTTPPUT)  1.5重命名文件/目录:RENAME(HTTPPUT)  1.6删除文件/目录:DELETE(HTTPDELETE) ......
  • nginx-gridfs Benchmarking Raw Results
    RawDataSpreadsheetwithtestresults(ODFformat)Thesefollowinglinksshowtherawoutputfromthebenchmarkingutilities.GridFSOverNetworkThistestscenarioshowsperformanceforHTTPrequestsoveragigabitEthernetLANconnection.MongoDBand......
  • 【蓝桥杯集训·周赛】AcWing 第96场周赛
    第一题AcWing4876.完美数一、题目1、原题链接4876.完美数2、题目描述如果一个正整数能够被2520整除,则称该数为完美数。给定一个正整数n,请你计算[1,n]范围内有多少个完美数。输入格式一个整数n。输出格式一个整数,表示[1,n]范围内完美数的个数。数据范围前3个测试点满......
  • 第十四届蓝桥杯大赛软件赛国赛 C/C++ 大学 A 组
    Preface蓝桥杯战俘闪总出列!逆天比赛早上9点要赶到六七公里外的其它学校,因此早上7点就起来了然后坐公交颠着颠着就到了成都工业学院的门口,还刚好看到了lyy佬,就一起溜去考场了到了考场看了一圈好多熟悉的面孔,应该都是集训队的学长啥的,但好多名字还是叫不出来然后好像8点半就能......
  • 第十四届蓝桥杯
    2023第十四届蓝桥杯省赛A.冶炼金属题目大意先放着解题思路先放着神秘代码#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;signedmain(){cout<<"HelloWorld"<<endl;}......
  • 【蓝桥杯集训·周赛】AcWing 第 95 场周赛
    第一题AcWing4873.简单计算一、题目1、原题链接4873.简单计算2、题目描述给定四个整数x1,y1,x2,y2,请你计算max(|x1−x2|,|y1−y2|)。输入格式第一行包含两个整数x1,y1。第二行包含两个整数x2,y2。输出格式一个整数,表示max(|x1−x2|,|y1−y2|)的值。数据范围前4个测试点......
  • HDFS Users Guide
    HDFSUsersGuideHDFSUsersGuidePurposeOverviewPrerequisitesWebInterfaceShellCommandsDFSAdminCommandSecondaryNameNodeCheckpointNodeBackupNodeImportCheckpointBalancerRackAwarenessSafemodefsckfetchdtRecoveryModeUpgradeandRollbackDataNodeHotSwap......
  • LeetCode----二维网格DFS
    1算法模板voiddfs(int[][]grid,intr,intc){//判断basecase//如果坐标(r,c)超出了网格范围,直接返回if(!inArea(grid,r,c)){return;}//访问上、下、左、右四个相邻结点dfs(grid,r-1,c);dfs(grid,r+1,c);......
  • [第五届蓝桥杯省赛C++B组]省赛全题目题解
    文章目录快速分支通道酒精与饮料切面条李白打酒史丰收运算打印图形奇怪的分式六角填数蚂蚁感冒地宫取宝小朋友排队1.题目啤酒和饮料算法标签:枚举题目描述:题目答案:题目思路:题目代码:2.题目切面条来源:第五届蓝桥杯省赛C++B组算法标签递推题目描述:题目答案:题目思路:题目代码:3.题目......