JakeLin- [Blue Bridge Cup] [2016 Seventh Zhenti] Path Riddle-Problem-DFS /バックトラッキング

タイトルの説明

小明は惑星Xの騎士を装って、奇妙な城に入る。城には何もなく、正方形の石で舗装された地面だけがありました。
城の床がnxnの正方形であるとします。[上記のとおり]。慣習によれば、騎士は北西の隅から南東の隅へと歩きます。
横や縦に動かすことはできますが、横に歩いたりジャンプしたりすることはできません。新しい正方形に到達するたびに、北と西に向かって矢印が1つずつ発射されます。
(城の西壁と北壁にはn個のターゲットがあります)
同じ正方形は1回しか通過できません。しかし、すべての正方形を通過する必要はありません。
ターゲットの矢印の数だけが与えられている場合、騎士の歩行ルートを推測できますか?
写真の例のように、それが可能な場合もあります。
この質問の要件は、矢のターゲットの数を把握し、騎士の歩行経路を探すことです(テストデータでは、経路が一意であることを確認しています)。

入力

最初の行の整数N(0 <N <20)は、地面にN x Nの正方形があることを示します
。2番目の行のスペースで区切られたNの整数は、北側(西から東)のターゲットの番号を示します。3
番目の行N西のターゲット(北から南)の数値を表す整数で、スペースで区切られています

アウトプット

行のいくつかの整数は、騎士の道を表しています。

便宜上、各小さなグリッドは北西の角から始まる番号で表されることに同意します:0,1,2,3...。たとえば
、図1.pngのブロック番号は次のとおりです:
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

元のタイトルのリンク:[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;
}

 

元の記事を20件公開 15 獲得 ビュー217

おすすめ

転載: blog.csdn.net/qq_37414463/article/details/105375385
おすすめ