今天是集训第二天,对深搜的概念理解的更深了,觉得回溯很巧妙。刚开始都要手动运行一遍,才真的摸清来龙去脉。今天A了两题(恨不得把所有代码都粘上)。昨天的代码终于知道哪里错了,因为我第一步在走之前没有标记,就是走着走着又会回到A1的位置,回溯大概就是在一种条件的前提下把所有情况都找一遍,然后返回上一级,把走过的部分路径清空。
一:以下是昨天的错题:
A Knight's Journey
一个骑士要把p*q的棋盘上的点都走一遍,要求按照最小字典序走,且不能重复走之前的点。列用大写字母表示,行用阿拉伯数字。
很显然,这道题运用的思想是深搜。
此题陷阱很多,要搞懂最小字典序,因为每一点都要走,肯定经过A1点,那么肯定是从A1开始;
然后要看清骑士走的是日字形。
其次再写代码的时候,要将输出的那部分用char来储存,开始我居然用的int呵呵。然后小细节,数字用char型输出时类似于x+'0'就好。
#include<iostream>
#include<string.h>
using namespace std;
int dx[8] = {-1, 1, -2, 2, -2, 2, -1, 1};
int dy[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
int visit[27][27]={0};
char shuchu[100][2];
int num,p,q;
int biaozhi=0;
void dfs(int x,int y,int num)
{
shuchu[num][0]=x+'0';
shuchu[num][1]=y+'A'-1;
if(num==p*q)
{
biaozhi=1;
return ;
}
else
{
for(int i=0;i<8;i++)
{
int dxx=x+dx[i];
int dyy=y+dy[i];
if(dxx>0&&dxx<=p&&dyy>0&&dyy<=q&&visit[dxx][dyy]==0&&biaozhi==0)
{
visit[dxx][dyy]=1;
dfs(dxx,dyy,num+1);
visit[dxx][dyy]=0;
}
}
}
}
int main()
{
int m,j;
cin>>m;
for(j=1;j<=m;j++)
{
cin>>p>>q;
memset(visit,0,sizeof(visit));
biaozhi=0;
visit[1][1]=1;//就是这个地方,简直了!!!
dfs(1,1,1);
cout<<"Scenario #"<<j<<":"<<endl;
if(biaozhi==0)
cout<<"impossible"<<endl;
else
{
for(int i=1;i<=p*q;i++)
{
cout<<shuchu[i][1]<<shuchu[i][0];
}
cout<<endl;
}
if(j!=m)
cout<<endl;
}
return 0;
}