- 链接http://noi.openjudge.cn/ch0205/8465/
- 描述
-
马在中国象棋以日字形规则移动。
请编写一段程序,给定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
查看
WA:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<string> #include<vector> #define DEBUG(x) cout<<#x<<" = "<<x<<endl using namespace std; int N,M; int x,y; int visited[15][15]; int dirx[]={-1,+1,-2,+2,-2,+2,-1,+1}; int diry[]={-2,-2,-1,-1,+1,+1,+2,+2}; int dfs(int r,int c,int step) {///已经走了step步,现在从r,c出发的 if(step==N*M){ return 1; } if(r<0||c<0||r>=N||c>=M||visited[r][c])return 0; visited[r][c]=1; int num=0; for(int i=0;i<8 ;i++ ){ num+=dfs(r+dirx[i],c+diry[i],step+1); } visited[r][c]=0; return num; } int main() { freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t--){ scanf("%d%d%d%d",&N,&M,&x,&y); memset(visited,0,sizeof(visited)); printf("%d ",dfs(x,y,0)); } }
AC:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<string> #include<vector> #define DEBUG(x) cout<<#x<<" = "<<x<<endl using namespace std; int N,M; int x,y; int visited[15][15]; int dirx[]={-1,+1,-2,+2,-2,+2,-1,+1}; int diry[]={-2,-2,-1,-1,+1,+1,+2,+2}; int dfs(int r,int c,int step) {///走到r,c走了step步,接下来的路径数目 if(r<0||c<0||r>=N||c>=M||visited[r][c])return 0; if(step==N*M){ return 1; } visited[r][c]=1; int num=0; for(int i=0;i<8 ;i++ ){ num+=dfs(r+dirx[i],c+diry[i],step+1); } visited[r][c]=0; return num; } int main() { // freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t--){ scanf("%d%d%d%d",&N,&M,&x,&y); memset(visited,0,sizeof(visited)); dfs(x,y,1); printf("%d ",dfs(x,y,1)); } }
这两份代码只有微小的差别。
已经走了step步,现在从r,c出发
走到r,c走了step步,接下来的路径数目
前者会造成路径的多算