Sicily马周游问题

简单马周游问题

http://soj.sysu.edu.cn/show_problem.php?pid=1152
思路:深搜
代码:

#include <stdio.h>
#include <string.h>

const int tot = 30;
int dr[] = {-2, -2, -1, +1, +2, +2, +1, -1};
int dc[] = {-1, +1, +2, +2, +1, -1, -2, -2};

void print_route(int route[], int n)
{
    printf("%d", route[0]);
    for (int i = 1; i < n; i++) {
        printf(" %d", route[i]);
    }
    printf("\n");
    return;
}

// curr in cell (row, col)
bool travel(int row, int col, int steps, int route[], bool vis[][6])
{
    if (steps == tot) {
        print_route(route, steps);
        return true;
    }
    int next_row, next_col;
    for (int i = 0; i < 8; i++) {
        next_row = row + dr[i]; // next = [1,30]
        next_col = col + dc[i];
        if (0<=next_row && next_row<=4 && 0<=next_col && next_col<=5 && !vis[next_row][next_col]) {
            vis[next_row][next_col] = true;
            route[steps] = next_row * 6 + next_col + 1;
            if (travel(next_row, next_col, steps + 1, route, vis))
                return true;
            vis[next_row][next_col] = false;
        }
    }
    return false;
}

int main()
{
    int n, row, col;
    bool vis[5][6]; // [1,30]
    int route[30];

    while(scanf("%d", &n) == 1 && n >= 1) {
        memset(vis, false, sizeof(vis));
        memset(route, 0, sizeof(route));
        row = (n - 1) / 6; // next = [1,30]
        col = (n - 1) % 6;
        vis[row][col] = true;
        route[0] = n;
        travel(row, col, 1, route, vis);
    }
    return 0;
}                                 

马的周游问题

http://soj.sysu.edu.cn/show_problem.php?pid=1153
优化:由于棋盘扩大了,想原来那样的深搜将超时。对下一步的选择进行优化:先沿着可行格子较少的邻居进行深搜
代码:

const int tot = 64;

int dr[] = {-2, -2, -1, +1, +2, +2, +1, -1};
int dc[] = {-1, +1, +2, +2, +1, -1, -2, -2};

struct Cell{
    int x, y;
    int cnt;
};

bool operator <(const Cell& a, const Cell& b) {
    return a.cnt > b.cnt;
} 

void print_route(int route[], int n)
{
    printf("%d", route[0]);
    for (int i = 1; i < n; i++) {
        printf(" %d", route[i]);
    }
    printf("\n");
    return;
}

// curr in cell (row, col)
bool travel(int row, int col, int steps, int route[], bool vis[][8])
{
    if (steps == tot) {
        print_route(route, steps);
        return true;
    }
    int r, c, next_row, next_col;
    priority_queue<Cell> cells;
    Cell temp;
    // 搜索可行格并排序 
    for (int i = 0; i < 8; i++) {
        r = row + dr[i]; 
        c = col + dc[i];  
        if (0<=r && r<=7 && 0<=c && c<=7 && !vis[r][c]) {// 对于某可行邻居:
            int cnt = 0;
            for (int j = 0; j < 8; j++) {
                next_row = r + dr[j];
                next_col = c + dc[j];
                if (0<=next_row && next_row<=7 && 0<=next_col && next_col<=7 && !vis[next_row][next_col]) {
                    cnt++;
                }
            }
            temp.x = r;
            temp.y = c;
            temp.cnt = cnt; //计算该邻居的可行格数目 
            cells.push(temp);
        }               
    }

    while(!cells.empty()) {
        temp = cells.top();
        cells.pop();
        next_row = temp.x; // next = [1,30]
        next_col = temp.y;
        vis[next_row][next_col] = true;
        route[steps] = next_row * 8 + next_col + 1;
        if (travel(next_row, next_col, steps + 1, route, vis))
            return true;
        vis[next_row][next_col] = false;    
    }   
    return false;
}

int main()
{
    int n, row, col;
    bool vis[8][8];
    int route[64];

    while(scanf("%d", &n) == 1 && n >= 1) {
        memset(vis, false, sizeof(vis));
        memset(route, 0, sizeof(route));
        row = (n - 1) / 8; // next = [1,30]
        col = (n - 1) % 8;
        vis[row][col] = true;
        route[0] = n;
        travel(row, col, 1, route, vis);
    }
    return 0;
}                                 
    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/sysuZhd/article/details/51247520
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞