POJ2488(DFS)

      这个题调试了几个晚上了。提交了好多次才AC。

先贴错误的代码:

#include<iostream>
#include<string>
using namespace std;

string que;
bool board[26][26];
int d[8][2]={{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};
int p,q;
void dfs(bool &tag,int sx,int sy,int k);

int main()
{
    int T,i,j,cnt = 1;
	cin>>T;
    
      do
      {
          cin>>p>>q;
		  que = "A1";
          for(i = 0 ; i < p ; ++i)
          for(j = 0 ; j < q ; ++j)
          board[i][j] = false;
          board[0][0] = true;

		  bool tag = false;
		 
          cout<<"Scenario #"<<cnt++<<":"<<endl;
          dfs(tag,0,0,1);
          if(!tag)
            cout<<"impossible"<<endl<<endl;
          else
          {
			cout<<que<<endl<<endl;
          }
          
      }while(--T);
    
   // system("pause");
    return 0;
}

void dfs(bool &tag,int sx,int sy,int k)
{
	if(tag) return ;
	if(k == p*q)
	{
			  tag =true;
	          return ;
	} 
	else
        for(int i = 0 ; i < 8 ; ++i)
		{ 
	      int dx = sx + d[i][0];
		  int dy = sy + d[i][1];
		   if(dx >= 0 && dx < p && dy >= 0 && dy < q && !board[dx][dy] && !tag)
		   {
              board[dx][dy] = true;
			  char ch = dy + 65;
			  int t = dx + 49;
			  que += ch;//加时很方便,回溯后就出错了
			  que += t;
			  cout<<k+1<<" "<<ch<<dx+1<<endl;
			  dfs(tag,dx,dy,k+1);
              /*最开始还忘了这个得回溯*/
			  board[dx][dy] = false;//这个是回溯了,但是错误的路径没有删除或者覆盖
			 
		   }//if()
		  
		 }//for()
             
}

 错误原因:

      对回溯认识不够深刻!还有对路径的处理不好!

   改进方案:

      string 是可以打下标当数组用的,修改修改就AC了。后来发现内存有点浪费!于是把string 改成 字符型数组了。提交后内存果然大大减少了!时间不提,因为都是0MS。

AC CODE:

#include<iostream>
using namespace std;

bool board[26][26];//棋盘 
int d[8][2]={{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};// 八个方向(字典序) 

int p,q;//棋盘长宽 
char que[53];//保存路径 
bool tag;//标记是否有可走的路径 
void dfs(int sx,int sy,int k);

int main()
{
    int T,i,j,cnt = 1;
    que[0] = 'A';//第一个位置是确定的,因为得按字典序 
    que[1] = '1';
	cin>>T;
    
      do
      {
          cin>>p>>q;
          for(i = 0 ; i < p ; ++i)
          for(j = 0 ; j < q ; ++j)
          board[i][j] = false;
          board[0][0] = true;//第一个位置每次都是起点,所以提前标记 
          tag = false;
		 
          cout<<"Scenario #"<<cnt++<<":"<<endl;
          dfs(0,0,1);
          if(!tag)
            cout<<"impossible"<<endl<<endl;
         
     }while(--T);
    
   // system("pause");
    return 0;
}

void dfs(int sx,int sy,int k)
{
	if(k == p*q)//找到可行解了 
	{
			  tag =true;
			  for(int i = 0 ;i < 2*k ;++i)
			  cout<<que[i];
              cout<<endl<<endl;
	          return ;
	} 
	else
        for(int i = 0 ; i < 8 ; ++i)
		{ 
	      int dx = sx + d[i][0];
		  int dy = sy + d[i][1];
		   if(dx >= 0 && dx < p && dy >= 0 && dy < q && !board[dx][dy] && !tag)
		   {
              board[dx][dy] = true;
			  char ch = dy + 65;
			  int t = dx + 49;
			  que[2*k]=ch;//每走一步就产生一个字母和一个数字,所以注意下标 
			  que[2*k+1]=t;//
			  dfs(dx,dy,k+1);
			  board[dx][dy] = false;//这个就是回溯了 
			  
		   }//if()
		  
		 }//for()
}
原文地址:https://www.cnblogs.com/HpuAcmer/p/2263048.html