人赢邱老师和任何男生比,都是不虚的。有一天,邱老师带妹子(们)来到了一个 N 行 M 列平面的小行星。对于每一个着陆地点,邱老师总喜欢带着妹子这样走:假设着陆地点为 (r0, c0) ,那么他们下一步只能选择相邻格点,向四周走,即 (r0–1, c0) , (r0 + 1, c0) , (r0, c0–1) 或 (r0, c0 + 1) 。之后的路程必须严格按照右转-前进-左转-前进-右转......的道路前行。但是由于邱老师很心疼妹子,所以崎岖的山脉不可以到达。当不能前进时必须要原路返回。如下图。
![妹子还是邱老师会泡](http://acm.uestc.edu.cn/images/problem/1086/2015042319065853536.jpg)
问,邱老师在哪里着陆可以游历这颗星球最多的土地,输出可能访问到的最多的格点数。
Input
第一行一个整数
T
,
0<T≤20
,表示输入数据的组数。
对于每组数据,第一行有两个整数
N
和
M
,分别表示行数和列数,
0<N,M≤1000
下面
N
行,每行
M
个字符(
0
或
1
)。
1
代表可到达的地方,
0
代表山脉(不可到达的地方)。
Output
对于每一组数据,输出一个整数后换行,表示选择某点着陆后,可能访问到的最多的格点数。
Sample input and output
Sample Input | Sample Output |
---|---|
2 4 3 111 111 111 111 3 3 111 101 111 | 10 4 |
#include <iostream>
#include <string.h>
using namespace std;
char map[1010][1010];
int dp[1010][1010][4][2]; //保存已算出结果的数组
int t,n,m;
int dfs(int x,int y,int dir,int turn)
{
int ans=0;
if (x>=0 && x<n && y>=0 && y<m && map[x][y]=='1')
{
if (dp[x][y][dir][turn]!=-1)
return dp[x][y][dir][turn];
if (dir==0) //上
{
if (turn==1) //上右 0 1
ans=dfs(x-1, y, 0, 0)+1; //走上上
else //上上 0 0
ans=dfs(x, y+1, 0, 1)+1; //走上右
}
else if(dir==1) //右
{
if (turn==0) //右右 1 0
ans=dfs(x+1, y, 1, 1)+1; //走右下
else //右下 1 1
ans=dfs(x, y+1, 1, 0)+1;//走右右
}
else if(dir==2) //下
{
if (turn==1) //下左 2 1
ans=dfs(x+1, y, 2, 0)+1; //走下下
else //下下 2 0
ans=dfs(x, y-1, 2, 1)+1;//走下左
}
else if(dir==3) //左上
{
if (turn==1) //3 1
ans=dfs(x, y-1, 3, 0)+1; //走左左
else //左左 3 0
ans=dfs(x-1, y, 3, 1)+1; //走左上
}
}
if(x>=0 && x<n && y>=0 && y<m)
return dp[x][y][dir][turn]=ans;
return 0;
}
int main()
{
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
//n=1000,m=1000;
getchar();
for (int i=0; i<n; i++)
{
scanf("%s",map[i]);
}
// memset(map, '1', sizeof(map));
memset(dp, -1, sizeof(dp));
int ans=0;
for (int i=0; i<n; i++)
{
for (int j=0; j<m; j++)
{
if (map[i][j]=='1')
{
int temp=1;
temp+=dfs(i-1,j,0,0);//上
temp+=dfs(i,j+1,1,0);//右
temp+=dfs(i+1,j,2,0);//下
temp+=dfs(i,j-1,3,0);//左
if (temp>ans)
ans=temp;
}
}
}
printf("%d\n",ans);
}
return 0;
}