1219:马走日

题目来源:http://ybt.ssoier.cn:8088/problem_show.php?pid=1219

1219:马走日


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 3106     通过数: 1646 

【题目描述】

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

请编写一段程序,给定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


不知道为什么我写的代码会超时:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<string>
 7 #include<cstdlib>
 8 #include<queue>
 9 #include<vector>
10 #define INF 0x3f3f3f3f
11 #define PI acos(-1.0)
12 #define N 101
13 #define MOD 2520
14 #define E 1e-12
15 using namespace std;
16 int f[15][15],T,n,m,x,y,vis[15][15],ans=0;
17 int dir[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};
18 void dfs(int h,int l,int step)
19 {
20     for(int i=0;i<8;i++)
21     {
22         if(vis[h][l]==0&&h>=0&&h<m&&l>=0&&l<n)
23         {
24             if(step==n*m){ans++;return;}
25             vis[h][l]=1;
26             dfs(h+dir[i][0],l+dir[i][1],step+1);
27             vis[h][l]=0;
28         }
29     }
30 }
31 int main()
32 {
33     memset(f,0,sizeof(f));
34     memset(vis,0,sizeof(vis));
35     scanf("%d",&T);
36     for(int i=1;i<=T;i++)
37     {
38         ans=0;
39         scanf("%d%d%d%d",&n,&m,&x,&y);
40         dfs(y,x,1);
41         printf("%d
",ans);
42     }
43     return 0;
44 }

问题出在dfs(h+dir[i][0],l+dir[i][1],step+1);这句这里。

为什么参考答案中

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #define N 10
 6 using namespace std;
 7 int n,m;
 8 int x0,y0;
 9 char maps[N][N];
10 int vis[N][N];
11 int dir[8][2]={{-2,1},{-2,-1},{-1,2},{-1,-2},{2,1},{2,-1},{1,2},{1,-2}};
12 int cnt;
13 void dfs(int x,int y,int step)
14 {
15     if(step==n*m)
16     {
17         cnt++;
18         return;
19     }
20     for(int i=0;i<8;i++)
21     {
22         int nx=x+dir[i][0];
23         int ny=y+dir[i][1];
24         if(nx>=0&&ny>=0&&nx<n&&ny<m&&vis[nx][ny]==0)
25         {
26             vis[nx][ny]=1;
27             dfs(nx,ny,step+1);
28             vis[nx][ny]=0;
29         }
30     }
31 }
32 int main()
33 {
34     int t;
35     cin>>t;
36     while(t--)
37     {
38         cnt=0;
39         memset(vis,0,sizeof(vis));
40  
41         cin>>n>>m;
42         cin>>x0>>y0;
43  
44         vis[x0][y0]=1;
45         dfs(x0,y0,1);
46         cout<<cnt<<endl;
47     }
48     return 0;
49 }

for(int i=0;i<8;i++)
    {
        int nx=x+dir[i][0];
        int ny=y+dir[i][1];
        if(nx>=0&&ny>=0&&nx<n&&ny<m&&vis[nx][ny]==0)
        {
            vis[nx][ny]=1;
            dfs(nx,ny,step+1);
            vis[nx][ny]=0;
        }
    }

这一段相比我写的就不会超时???

难道是系统栈的调用问题?我的增量写在dfs里面,参考答案是每次新开一个变量来容纳下一步的位置。但是实际上二者是等价的。

经过多次尝试,发现问题确实出在这上面,也就是系统栈。难道是由于我写的递归搜索方案中每次需要在函数调用过程中计算下一次的位置,而这样会消耗大量资源?

emmm

原文地址:https://www.cnblogs.com/DarkValkyrie/p/10587483.html