C实现KnightsTour(编译通过)

Problem Statement

    

Facebook engineers love playing chess. They also like to play other  games on the chessboard. Today, they were wondering how many cells a knight  would visit on the chessboard if it followed some predefined algorithm.

 

You are given a String[] board describing a standard 8x8  chessboard, where the c-th character of the r-th element corresponds to the  cell in row r, column c. Some cells are blocked and cannot be jumped into.  These will be represented with a '*'. All other cells are marked with a '.',  except for the starting position of the knight, which is marked with a 'K'.

 

A valid jump for a knight consists of shifting one square along one axis  and two squares along the other axis. A cell is "accessible" if it  is not blocked and it has not been visited by the knight before. The starting  position of the knight is considered to be visited, and each time the knight  jumps into a new cell, that cell becomes visited. The accessibility number of  a cell is the number of accessible cells that the knight can make a valid  jump to from that cell. Note that accessibility numbers of cells may change  as the knight moves through the board and visits more cells.

 

The knight will use the following simple algorithm to traverse the  board. On each move, it will make a valid jump into the accessible cell with  the lowest accessibility number. In case of a tie, it will choose the one  with the lowest row number, and if there is still a tie, it will choose the  one among them with the lowest column number. The knight will stop moving when  it can no longer make a valid jump into an accessible cell.

 

Return the number of cells that the knight will visit (including the  starting cell).

Definition

    

Class:

KnightsTour

Method:

visitedPositions

Parameters:

String[]

Returns:

int

Method signature:

int visitedPositions(String[] board)

(be sure your method is public)

    

Constraints

-

board will contain  exactly 8 elements.

-

Each element of board will contain exactly 8  characters '.', 'K' or '*'.

-

Character 'K' will appear exactly once in board

Examples

0)

    

{"........"

,".*.*...."

,".*......"

,"..K...*."

,"*...*..."

,"...*...."

,"...*.*.."

,"........"}                     

Returns: 39               

From its starting cell K, the knight can jump to      cells A, B and C, which have accessibility numbers of 3, 6 and 4,      respectively (see first image below). It will jump to cell A because it      has the lowest accessibility number.

 

From cell A, it can then jump to cells D, E and F,      which have accessibility numbers of 1, 5 and 4, respectively (see second      image). It will choose cell D. It will continue in this fashion and visit      a total of 39 cells.


                                                                                                                                                                           

1)

    

{"K......."

,"........"

,"........"

,"........"

,"........"

,"........"

,"........"

,"........"}                     

Returns: 64               

If no cells are blocked, then the knight will      end up visiting every cell by following the given algorithm.

2)

    

{"********"

,"*******."

,"********"

,"**.***.*"

,"********"

,"***.*.**"

,"********"

,"****K***"}                     

Returns: 3               

From its starting cell K, the knight can jump to      cells A and B, which have accessibility numbers of 1 (see the image).      Both A and B have the same accessibility number and the same row number,      so it will jump to A because it has the lowest column number. It will      then jump to C and stop, visiting a total of 3 cells.


                                  

3)

    

{"*.*....*"

,".......*"

,"**...*.."

,"..***..."

,".**.*..."

,"..*.*..K"

,"..***.*."

,"**...*.."}                     

Returns: 17               

4)

    

{"..*...*."

,"**.....*"

,"*..*...."

,"*..*...."

,".....*.."

,"....*..K"

,"**.*...*"

,"..**...."}                     

Returns: 27               

This problem statement is the exclusive and proprietary property ofTopCoder, Inc. Any unauthorized use or reproduction of this information withoutthe prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003,TopCoder, Inc. All rights reserved.

 //C代码如下

/*
 *
 *KnightsTour
 *
 *
 *Author:stand
 *Date:  2012.7.12
 *Description:
 *      1.当N>6时,时间复杂度增加;程序运行时能明显感觉到时间延长;
*/


#include <stdio.h>
#include <cstdlib>

#define N 8        // N*N方阵

int stack[N*N][3];   //设置一个全程的数组,存储8个步骤过程,及过程
int top=0;           //设置全程的变量top.

//push()函数用来表示压栈操作
 
void push(int i,int j,int k)
{                
    stack[top][0]=i;
    stack[top][1]=j;
    stack[top][2]=k;
    top++;
}

//pop()函数用来表示出栈操作
void pop()
{
    top--;
}

 
int main()
{
 int x,y;   //棋盘坐标下标
 int v=0;     //移动方向计数
 int i,j;   //遍历数组时下标
 int move[8][2]={2,1,1,2,1,-2,2,-1,-2,1,-1,2,-1,-2,-2,-1};    //设置8个方向
 int knight[N][N]={0};  //打印棋盘路线
 int count=0;           //计数骑士走的步数
 
 printf("输入开始棋盘的x下标:");
 scanf("%d",&x);
 printf("输入开始棋盘的y下标:");
 scanf("%d",&y);
 puts("结果如下:");
 
 //判断输入边界
 if(x<0||x>=N || y<0||y>=N)
   {
    printf("输入的下标超出边界,退出");
    system("pause");   
    exit(1);  
   }
 
 //实现骑士巡游算法
 while(count<N*N-1)
   {
    while(v<8)
      {
        i=x+move[v][0];
        j=y+move[v][1];
        if(i>=0&&i<N&&j>=0&&j<N&&knight[i][j]==0)  //有通路
          {             
           push(x,y,v+1);//若一个位置可走,则把前一个位置及下一个要走的方向压栈
        
           count++;
           knight[x][y]=count;
           x=i;                                 //跳到下一个的x下标
           y=j;                                 //跳到下一个的y下标
           v=0;                                 //方向从头开始试探
          }
        else
          v++;                                   //如果方向不通,试探下一个方向
      }
     
    if(v==8&&count>0&&count!=N*N-1)              //如果8个方向都没有找到,步数减一
      {
       pop();
     
       x=stack[top][0];
    y=stack[top][1];
    v=stack[top][2];
              
       knight[x][y]=0; 
       count--;  
      }     
   }   
    
 knight[x][y]=N*N;    
 //遍历打印棋盘路线
 for(i=0;i<N;i++)
   {
    for(j=0;j<N;j++)
      {
       printf("%3d",knight[i][j]);
      }
    printf("\n");     
   }
  
  
 system("pause"); 
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值