[sitge cup · blue bridge on cloud - algorithm training camp] the mystery of the path in week 2

Posted by bugsuperstar37 on Tue, 18 Jan 2022 09:56:13 +0100

Xiao Ming pretends to be the knight of Planet X and enters a strange castle.

There was nothing in the castle, only the ground made of square stones.

Suppose the castle ground is n x n squares. [as shown in Figure 1.png].

According to custom, knights walk from the northwest corner to the southeast corner.

It can move horizontally or vertically, but it can't walk obliquely or jump.

Every time you come to a new square, you have to shoot an arrow to the north and West.

(there are n targets in the west wall and N targets in the north wall of the castle)

The same square can only pass once. But you don't have to finish all the squares.

If you only give the number of arrows on the target, can you infer the knight's route?

Sometimes it is possible, such as Figure 1 Png example.

The requirement of this question is to know the target number and find the knight's walking path (the test data ensure that the path is unique)

Input:

The first line is an integer n (0 < n < 20), indicating that there are N x N squares on the ground

The second line contains N integers, separated by spaces, indicating the number on the North target (from west to East)

The third line contains N integers, separated by spaces, indicating the number on the target in the West (from north to South)

Output:

Several integers on a line 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, figure 1 The block number in PNG is:

0  1  2  3

4  5  6  7

8  9  10 11

12 13 14 15

Example:

User input:

4

2 4 3 4

4 3 3 3

The program should output:

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

Resource agreement:

Peak memory consumption < 256M

CPU consumption < 1000ms

Please output in strict accordance with the requirements, and do not print like "please input..." Superfluous content.

All code is placed in the same source file. After debugging, the copy is submitted to the source code.

Note: do not use package statements. Do not use jdk1 7 and above.

Note: the name of the Main class must be: Main, otherwise it will be treated as an invalid code.

This problem can only have one way at a glance, and there is no restriction on the map. Just find a path that matches the meaning of the topic.

It is the classic application of backtracking method.

What is backtracking?

In my opinion, backtracking is using multiple deep searches. That is, the choice of each direction can be regarded as a subtree extending from the starting point. If we only use one depth search, we can only find the subtree in one direction. At this time, using backtracking, we can find the subtree in one direction and return to root again to find the subtree in the next direction. So as to really list all possible paths to find the only path on the answer.

The code is as follows:

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int io[4]={1,-1,0,0};
int jo[4]={0,0,1,-1};
int color[20][20]={0};
int jj[20];
int ii[20];
int n;
vector<int> tr;
struct point {
    int i;
    int j;
};
int main(){
    void back(point s);
    cin >> n;
    
    for(int i=0;i<n;i++)
        scanf("%d",&jj[i]);

    for(int i=0;i<n;i++)
        scanf("%d",&ii[i]);
    
    point s={0,0};
    
    back(s);
    return 0;

}
void back(point s){
    
    int check(int *a,int *b,int n);
    if(s.i==n-1&&s.j==n-1){
        ii[s.i]--;
        jj[s.j]--;
        tr.push_back(s.i*n+s.j);
        if(check(ii,jj,n)){
            for(int i=0;i<tr.size()-1;i++)
                cout << tr[i] << ' ' ;
            cout << tr[tr.size()-1] ;
        }
        ii[s.i]++;
        jj[s.j]++;
        tr.pop_back();
    }
    if(check(ii,jj,n))
        return ;
    
    if(s.j<0 || s.i<0)
        return ;
    if(s.j>=n||s.i>=n)
        return ;
    
    for(int i=0;i<n;i++)
        if(ii[i]<0 || jj[i]<0)
            return ;
    
    if(color[s.i][s.j])
        return ;
    

    color[s.i][s.j]=1;
    ii[s.i]--;
    jj[s.j]--;
    tr.push_back(s.i*4+s.j);
        
    
    for(int p=0;p<4;p++){
        
        point next={s.i+io[p],s.j+jo[p]} ;
        back(next);
       
    }
        
    

    color[s.i][s.j]=0;
    ii[s.i]++;
    jj[s.j]++;
    tr.pop_back();
    return ;

}
int check(int *a,int *b ,int n){
    for(int i=0;i<n;i++)
        if(a[i]!=0 || b[i]!=0)
            return 0;
    return 1;
}

Topics: Algorithm