骑士巡游问题

问题:

  在 n × n 方格的国际象棋棋盘上,马(也称为骑士Knight)从任意指定的方格出发,以跳马规则(横一步竖两步或横两步竖一步),周游棋盘的每一个格子,要求每个格子只能跳过一次。

代码:

  思路什么的都在代码里,但是我写的代码太肤浅了, 5*5 的规模都要跑半天。

  所以真切的希望大家能够提出对我算法的批评与指教。

#include<iostream>
#include<fstream>
using namespace std;

//定义了8个方向,N表示右上的那个位置
#define N 0
#define NE 1
#define E 2
#define SE 3
#define S 4
#define SW 5
#define W 6
#define NW 7

struct step {//骑士巡游过的地方
    int x;
    int y;
};

void display(step steps[], int n)
{//展示骑士巡游的过程
    ofstream output("output.txt");
    int patch[10][10]={0};
    for (int i = 1; i <= n*n; i++)
    {
        patch[steps[i].x][steps[i].y]=i;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cout<<patch[i][j]<<"    ";
            output<<patch[i][j]<<"    ";
        }
        cout<<endl;
        output<<endl;
    }
    cout<<endl;
    output<<endl;
}

bool isInside(int n, step place)
{//判断是否走出了地图
    if (place.x<1 || place.x>n || place.y<1 || place.y>n) return false;
    return true;
}

bool isOverlap(int map[][8], step place)
{//判断是否走重了
    if (map[place.x][place.y] == 1) return true;
    return false;
}

step overlook(step now, int dir)
{//往dir方向向前看一步,返回这样走之后的位置
    step then;
    switch (dir)
    {
    case N:then.x = now.x + 1, then.y = now.y - 2; break;
    case NE:then.x = now.x + 2, then.y = now.y - 1; break;
    case E:then.x = now.x + 2, then.y = now.y + 1; break;
    case SE:then.x = now.x + 1, then.y = now.y + 2; break;
    case S:then.x = now.x - 1, then.y = now.y + 2; break;
    case SW:then.x = now.x - 2, then.y = now.y + 1; break;
    case W:then.x = now.x - 2, then.y = now.y - 1; break;
    case NW:then.x = now.x - 1, then.y = now.y - 2; break;
    }
    return then;
}

void patrol(step steps[], int now, step then, int map[][8])
{//从now的位置向dir方向巡游下一步
    steps[now + 1] = then;
    //在map上标记已经走过
    map[steps[now + 1].x][steps[now + 1].y] = 1;
}

void KnightPatrol(int n, int count, step steps[], int map[][8])
{//n表示棋盘规模,count表示骑士已经走过的步数,steps记录骑士巡游过的点,map用来标记地图上每个点有没被走过

    if (count > n*n)
    {//如果骑士巡游过了所有的点
        display(steps, n);
    }

    for (int i = N; i <= NW; i++)
    {//对每个方向遍历

        step then = overlook(steps[count], i);//向i方向眺望一下
        if (isInside(n, then) && !isOverlap(map, then))
        {//如果骑士下一步没有跑到地图外面,且没有走到刚才走过的地方

            patrol(steps, count, then, map);
            for(int k=1;k<=count+1;k++)
            {
                cout<<steps[k].x<<","<<steps[k].y<<" ";
            }
            cout<<endl;
            KnightPatrol(n, count + 1, steps, map);
            map[steps[count+1].x][steps[count+1].y]=0;
        }
    }
}

int main()
{
    int n;
    cin >> n;
    step *steps = new step[n*n + 1];
    steps[1].x = 3;
    steps[1].y = 1;
    int map[8][8] = { 0 };
    map[3][1] = 1;
    KnightPatrol(n, 1, steps, map);
    system("pause");
}
时间: 2024-11-05 04:59:37

骑士巡游问题的相关文章

POJ2488 A Knight&#39;s Journey 骑士巡游 DFS

Description Background The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular

每天刷个算法题20160523:骑士巡游的递归转非递归解法

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51524728 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

UVa439

Knight Moves 题意:骑士巡游到某位置的最少步数 #include <stdio.h> #include <string.h> int s[20][20]; int rear, front; int min; char a, c; int b, d; struct { int x, y; int p; }Susake[300000]; void bfs(int n, int m) { int t; rear++; Susake[rear].x = n; Susake[re

hdu 1372 AND poj 2243 bfs

骑士巡游找最短路. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 8; 7 const int M = N * N; 8 int step[N][N]; 9 int dir[N][2] = { 1, 2, 1, -2, -1, 2, -1, -2, 2, 1, 2, -1, -2, 1, -2, -1 }; 1

[COGS746] [网络流24题] 骑士共存

★★☆   输入文件:knight.in   输出文件:knight.out   简单对比 时间限制:1 s   内存限制:128 MB 骑士共存问题 «问题描述: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘 上某些方格设置了障碍,骑士不得进入. «编程任务: 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑 士,使得它们彼此互不攻击. «数据输入: 由文件knight.in给出输入数据.第一行有2 个正整数n 和m (1<=n<

【Codevs1922】骑士共存问题(最小割,二分图最大匹配)

题意: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击. n<=200,m<=n^2 思路:经典的二分图最大匹配问题,采用黑白点染色的思想. 如果按照相邻点黑白不同染色,可以发现每次跳到的点必定与现在所在点不同色,二分图最大匹配即可. 这里用最小割来解决,因为不能允许任何黑白点之间的任何一条边有流量,符合最小割的思想. 1

【树形DP】BZOJ1040-[ZJOI2008]骑士

[题目大意] 有n个骑士,给出他们的能力值和最痛恨的一位骑士.选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力,求战斗力的最大值. [思路] 首先yy一下,可以知道这是一个基环森林.我们可以用以下方法: 首先在每一棵基环树的环上任意找到一条边(用dfs来实现),记它的两个端点为u和v.然后删掉这条边(我这里用的方法是记录u,v在对方容器中的位置,并在后续操作中忽略这条边).由于u和v不能同时取,在删掉u和v之间

bzoj1040 骑士

Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队.于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶.骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾.每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不

骑士飞行棋第三版(上色)

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 骑士飞行棋 8 { 9 class Program 10 { 11 12 //在下面的数组存储我们游戏地图各个关卡 13 //数组的小标为0的元素对应地图上的第一格 下标为1的元素对应第二格...下标为n的元素对应n+1