有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:
a. 每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;
b. 走过的格子立即塌陷无法再走第二次;
c. 只能向北、东、西三个方向走;
请问:如果允许在方格矩阵上走 nn 步,共有多少种不同的方案。
22 种走法只要有一步不一样,即被认为是不同的方案。
输入格式
允许在方格上行走的步数 n(n \le 20)n(n≤20)。
输出格式
计算出的方案数量。
Sample 1
Inputcopy | Outputcopy |
---|---|
2 | 7 |
这一题我一上来就想到用深搜,因为它的特点就是不会走重复的路,所以就开始了我深搜求解之路,但是我发现最后结果提交只能保证样例通过,然后我就开始debug,下面是我的代码,老手肯定一眼看出来,我在后面揭晓哪里WA了
dfs版本代码如下:
//错误的样例代码
#include<iostream>
using namespace std;
bool vis[100][100];
int sum=0;
int dir[3][2]={{0,-1},{-1,0},{0,1}};
struct pos
{
int x,y;
int s;
}cur,nex;
int n;
void dfs(pos cur)
{
vis[50][50]=1;
if(cur.s==n)
{
sum++;
cout<<'('<<cur.x<<','<<cur.y<<')'<<endl;
return;
}
for(int i=0;i<3;i++)
{
nex.x=cur.x+dir[i][0];
nex.y=cur.y+dir[i][1];
nex.s=cur.s+1;
if(!vis[nex.x][nex.y])
{
vis[nex.x][nex.y]=1;
dfs(nex);
vis[nex.x][nex.y]=0;
}
}
}
int main()
{
cin>>n;
cur.x=50,cur.y=50;
dfs(cur);
cout<<sum;
return 0;
}
竟然是我的变量用错了 ,可以看到我建造了一个结构体,然后竟然拿着bfs那一套把这个结构体变量放进循环然后参与深搜,这是万万不可的啊,后来发现,这样的话会不断的改变这个结构体变量的,肯定不对,正确的是,在dfs中重新定义下一个可能的位置x,y,然后在重新进入循环,直到满足条件为止。接下来是正确的AC代码
#include<iostream>
using namespace std;
bool vis[100][100];
int sum=0;
int dir[3][2]={{0,-1},{-1,0},{0,1}};
int n;
void dfs(int x,int y,int step)
{
if(step==n)
{
sum++;
// cout<<'('<<cur.x<<','<<cur.y<<')'<<endl;
return;
}
for(int i=0;i<3;i++)
{
int dx=x+dir[i][0];
int dy=y+dir[i][1];
if(vis[dx][dy]==0)
{
vis[dx][dy]=1;
dfs(dx,dy,step+1);
vis[dx][dy]=0;
}
}
}
int main()
{
cin>>n;
vis[50][50]=1;
dfs(50,50,0) ;
cout<<sum;
return 0;
}
递归版本代码:
看过了dfs你肯定会抱怨怎么会这么长,好麻烦,别急,还有递归解法,详细AC代码及注释参考如下
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int up[30],lift[30],right[30],sum[30];//定义走特定某一步时最大的 ,
//向每个方向走的步数
//定义走一步时可能向 三个方向走的步数
up[1]=1,lift[1]=1,right[1]=1,sum[1]=3;//其中sum是走一步可能的方案
for(int i=2;i<=20;i++)
{//本次方案是由上一次的方案在可能的情况下产生的
up[i]=lift[i-1]+right[i-1]+up[i-1]; //向上走,每一种都可以
lift[i]=up[i-1]+lift[i-1];//向左是左和上
right[i]=right[i-1]+up[i-1];
sum[i]=right[i]+lift[i]+up[i];
}
cout<<sum[n];
return 0;
}
这道题肯定是递归比较简单,写dfs的目的是为了巩固,不能见捡了芝麻丢西瓜对吧