有关SPOJ TOURIST的问题

时间:2016-07-19 05:33:34

标签: algorithm recursion dynamic-programming computer-science tail-recursion

问题陈述:

  

一个懒惰的游客想要去一个城市的许多有趣的地方   尽可能不进一步超越必要。开始   他打算从他位于城市西北角的酒店出发   散步到城市的东南角,然后步行   背部。走到东南角时,他只会向东走或走   向南,当他走回西北角时,他只会   向北或向西走。在研究了城市地图后,他意识到了这一点   任务不是那么简单,因为某些区域被阻止了。因此他有   请你写一个程序来解决他的问题。

     

给出城市地图(2D网格)所在的有趣位置和   被标记的区域被确定,确定有趣的最大数量   他可以访问的地点。访问过两次的地点只计算一次。

     

输入

     

输入中的第一行包含测试用例的数量(最多   20)。然后按照案例。每个案例都以一行包含   两个整数,W和H(2≤W,H≤100),宽度和高度   城市地图。然后跟随H行,每行包含一个带W的字符串   具有以下含义的字符:

 . Walkable area
 * Interesting location (also walkable area)
 # Blocked area
     

您可以假设左上角(起点和终点)和   右下角(转折点)是步行的,那是一个可步行的   长度为H + W - 2的路径存在于它们之间。

     

输出

     

对于每个测试用例,输出一个包含单个整数的行:   懒人游客可以访问的最多有趣地点。

     

实施例

Input: 
   2 9 7
*........
 .....**#. 
 ..**...#* 
 ..####*#. 
 .*.#*.*#. 
 ...#**...
*........ 
5 5
  .*.*.
*###.
*.*.* 
 .###* 
 .*.*.
     

输出:7 8

我的解决方案:

#include <iostream>

using namespace std;

char path[101][101];
int sz1,sz2;
int solve(int a,int b,int i,int j){
if(a>=sz1||b>=sz2||i>=sz1||j>=sz2){
   return 0;
   }
   int c = 0;
if(path[a][b]=='#'||path[i][j]=='#')
    return -100;
if(path[a][b]=='*'){
    c = 1;
    }
if(path[i][j]=='*'&&a!=i)
    c++;
int x =max(max(solve(a,b+1,i+1,j),solve(a+1,b,i+1,j)),max(solve(a,b+1,i,j+1),solve(a+1,b,i,j+1)));

return x+c;
}

int main()
{
int t;
cin>>t;
while(t--){
cin>>sz1>>sz2;

for(int i=0;i<sz1;i++){
    for(int j=0;j<sz2;j++)
        cin>>path[i][j];
}

cout << solve(0,0,0,0) << endl;
}
}

我还没有使用过memoization,因为我只是想编写一个回溯函数。但我对第一个测试用例的答案是错误的。正确的答案是7,但是这段代码打印出10.这个递归解决方案有什么问题?

1 个答案:

答案 0 :(得分:2)

你应该交换sz1和sz2。

第一行输入分别给出列数和行数。但是你以相反的顺序对待它们。