马的遍历(贪心)

/**
 * function:马的遍历。在8x8方格的棋盘上,从任意指定的方格出发,
 *          为马寻找一条走遍棋盘每一格并且只经过一次的一条路径。
 * author:顾博君
 * time:2013-1-23
 */
/*
 * 采用Warnsdoff策略求解。找出出口最少的点。
 *  ---------------------
    |   | 4 |   | 3 |   |
    ---------------------
    | 5 |   |   |   | 2 |
    ---------------------
    |   |   | · |   |   |
    ---------------------
    | 6 |   |   |   | 1 |
    ---------------------
    |   | 7 |   | 0 |   |
    ---------------------
 */

#include <stdio.h>
#include <windows.h>
#define N 8 //棋盘大小
int delta_i[]={ 2, 1,-1,-2,-2,-1, 1, 2};//马的8中走棋方式
int delta_j[]={ 1, 2, 2, 1,-1,-2,-2,-1};
int board[N][N];//棋盘
int exitn(int i,int j,int s,int a[]){
    //s用于改变a[]数组内容的顺序
    int i1,j1,k,count;
    for(count=k=0;k<N;k++){
        //求出下一个点
        i1=i+delta_i[(s+k)%N];
        j1=j+delta_j[(s+k)%N];
        //判断这个点是否在棋盘内并且没有走过
        if(i1>=0 && i1<N && j1>=0 && j1<N && board[i1][j1]==0)
            a[count++]=(s+k)%N;//记录下这个点在数组中的下标
    }
    return count;//返回可以走的下一个点的个数
}
int next(int i,int j,int s){
    int m;//记录可以走的下一个点的个数
    int k,kk,min,a[N],b[N],temp;
    m=exitn(i,j,s,a);
    if(m==0) return -1;//如果没有可以走的点,返回-1
    for(min=N+1,k=0;k<m;k++){//找出口最少的点
        temp=exitn(i+delta_i[a[k]],j+delta_j[a[k]],s,b);
        if(temp<min){
            min=temp;
            kk=a[k];
        }
    }
    return kk;//返回出口最少的点
}
int main(){
    int sx,sy,i,j,step,no,start;
    //开始遍历所有的点。
    for(sx=0;sx<N;sx++){
        for(sy=0;sy<N;sy++){
            //开始寻找以(sx,sy)为入口的路径
            start=0;
            do{
                //棋盘初始化
                for(i=0;i<N;i++){
                    for(j=0;j<N;j++){
                        board[i][j]=0;
                    }
                }
                board[sx][sy]=1;//在棋盘上记录步数
                //更新当前点
                i=sx;j=sy;
                for(step=2;step<N*N;step++){
                    if((no=next(i,j,start))==-1)break;//找下一个点
                    //更新当前点
                    i+=delta_i[no];
                    j+=delta_j[no];
                    board[i][j]=step;//在棋盘上记录步数
                }
                //if(step>N*N)break;
                start++;//可能出口的选择顺序
            }while(step<N*N);
            printf("起始点:(%d,%d)\n",sx,sy);
            //打印棋盘
            for(i=0;i<N;i++){
                for(j=0;j<N;j++){
                    printf("%4d",board[i][j]);
                }
                printf("\n\n");
            }
            scanf("%*c");
            system("cls");
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值