JakeLin- [Blue Bridge Cup] [2016 Seventh Zhenti] Path Riddle-Problem-DFS / Backtracking

Title description

Xiao Ming poses as a knight of Planet X and enters a strange castle. There was nothing in the castle, only the ground paved with square stones.
Suppose the castle floor is nxn squares. 【As shown in FIG. According to custom, the knight walks from the northwest corner to the southeast corner.
You can move it horizontally or vertically, but you can't walk sideways or jump. Every time a new square is reached, one arrow is shot each towards the north and west.
(There are n targets in the west wall and north wall of the castle) The
same square can only be passed once. But it is not necessary to go through all the squares.
If only the number of arrows on the target is given, can you infer the knight's walking route?
Sometimes it is possible, such as the example in the picture.
The requirement of this question is to know the number of the arrow target, and seek the walking path of the knight (the test data ensures that the path is unique)

Input

In the first line, an integer N (0 <N <20) indicates that there are N x N squares on the ground. In the
second line, N integers, separated by spaces, indicate the number on the target on the north side (from west to east).
Third line N Integers, separated by spaces, representing the numbers on the west target (from north to south)

Output

Several integers in a row represent the knight path.

For convenience, we agree that each small grid is represented by a number, starting from the northwest corner: 0,1,2,3 .... For
example, the block numbers in Figure 1.png are:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

Sample input

4
2 4 3 4
4 3 3 3

Sample output

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

Original title link: [Blue Bridge Cup] [2016 Seventh Zhenti] Path Mystery 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 25;
int map[maxn][maxn];   //地图
int to_north[maxn],to_west[maxn];  //目标
int north[maxn],west[maxn];  //统计靶子箭数
int vis[maxn][maxn];  //标记是否访问
int dx[]={0,0,1,-1};  //四个方向
int dy[]={1,-1,0,0};
int n;
vector<int> road; //存储路径,相当于递归中的栈
int res[maxn];
void dfs(int x,int y){
    //加速作用,若访问此节点靶子箭数超过目标则无需判断
    if(north[y]+1 > to_north[y] || west[x]+1 > to_west[x]){  
        return;
    }
    north[y]++;
    west[x]++;
    vis[x][y]=1;
    road.push_back(map[x][y]);
    if(x==n-1 && y==n-1){  //到达终点
        int tag = 1;
        for(int i=0;i<n;i++){   //判断靶子是否达到想要的最终状态
            if(north[i]!=to_north[i] || west[i]!=to_west[i]){
                tag=0;
                break;
            }
        }
        if(tag==1){  //符合条件
            for(int i=0;i<road.size();i++){
                cout<<road[i]<<" ";
            }
            return;
        }
    }
    for(int i=0;i<4;i++){   //遍历四个可达(不越界)方向
        int newx = x + dx[i];
        int newy = y + dy[i];
        if(newx>=0 && newx<n && newy>=0 && newy<n && vis[newx][newy]==0){
            dfs(newx,newy);
        }
    }
    //回溯,回到上一个点的状态
    north[y]--;
    west[x]--;
    road.pop_back();
    vis[x][y]=0;    
}
int main(){
    //初始化
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>to_north[i];
    }
    for(int i=0;i<n;i++){
        cin>>to_west[i];
    }
    int cnt=0;
    for(int i=0;i<n;i++){  //傻傻的做法
        for(int j=0;j<n;j++){
            map[i][j]=cnt++;
        }
    }    
    //调用DFS,从(0,0)开始
    dfs(0,0);
    return 0;
}

 

Published 20 original articles · won 15 · views 217

Guess you like

Origin blog.csdn.net/qq_37414463/article/details/105375385