#include

002:马走日

002:马走日

题目链接:http://cxsjsxmooc.openjudge.cn/2017t2summerfinal/002/

总时间限制:
1000ms
内存限制:
1024kB
描述

马在中国象棋以日字形规则移动。

请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。

输入
第一行为整数T(T < 10),表示测试数据组数。
每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标n,m,x,y。(0<=x<=n-1,0<=y<=m-1, m < 10, n < 10)
输出
每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,0为无法遍历一次。
样例输入
1
5 4 0 0
样例输出
32

/*
应该是数据有点弱
本来想先交一下看看不优化能跑多少样例
谁知道直接过了....... 

*/ 
#include <cstdio>
#include <cstring>
#define maxn 10
//马向八个方向走的偏移量 
int dirx[] = {-2 , -2 , -1 , -1 , 1 , 1, 2 , 2 } ; 
int diry[] = {-1 , 1 , -2 , 2 , -2 , 2 , -1 , 1 } ; 
int visit[maxn][maxn] ; 
int n , m ; 
int times = 0 ; 

bool check(int x , int y){
    if(x>=0&&x<n&&y>=0&&y<m)
    return true ; 
    return false ; 
}

void DFS(int x , int y , int step){
    if(step == n*m){
        times ++ ;
        return; 
    }
    int turnx , turny ; 
    for(int i=0 ; i<8 ; i++){
        turnx = x + dirx[i] ; 
        turny = y + diry[i] ; 
        if(check(turnx , turny)&&!visit[turnx][turny]){
            visit[turnx][turny] = 1 ; 
            DFS(turnx , turny , step+1) ; 
            visit[turnx][turny] = 0 ; // 回溯时 撤销标记  为搜寻下一种可能性 做准备 
        }
    }
    return;
}

int main(){
    int t , x , y ; 
    scanf("%d" , &t) ; 
    while(t--){
        times = 0 ; 
        scanf("%d%d%d%d" , &n , &m , &x , &y ) ; 
        memset(visit , 0 , sizeof(visit)) ; 
        visit[x][y] = 1 ; 
        DFS(x , y , 1 ) ; 
        printf("%d\n" , times) ; 
    }
    return 0 ; 
}

 

posted @ 2017-09-24 01:18  0一叶0知秋0  阅读(195)  评论(0编辑  收藏  举报