2015 UESTC 搜索专题B题 邱老师降临小行星 记忆化搜索

邱老师降临小行星

Time Limit: 20 Sec  Memory Limit: 256 MB

题目连接

http://acm.uestc.edu.cn/#/contest/show/61

Description

人赢邱老师和任何男生比,都是不虚的。有一天,邱老师带妹子(们)来到了一个N行M列平面的小行星。对于每一个着陆地点,邱老师总喜欢带着妹子这样走:假设着陆地点为(r0, c0),那么他们下一步只能选择相邻格点,向四周走,即(r0–1, c0), (r0 + 1, c0), (r0, c0–1)或(r0, c0 + 1)。之后的路程必须严格按照右转-前进-左转-前进-右转......的道路前行。但是由于邱老师很心疼妹子,所以崎岖的山脉不可以到达。当不能前进时必须要原路返回。如下图。

妹子还是邱老师会泡

问,邱老师在哪里着陆可以游历这颗星球最多的土地,输出可能访问到的最多的格点数。

Input

第一行一个整数T, 0<T≤20,表示输入数据的组数。 对于每组数据,第一行有两个整数N和M,分别表示行数和列数,0<N,M≤1000 下面N行,每行M个字符(0或1)。 1代表可到达的地方,0代表山脉(不可到达的地方)。

Output

对于每一组数据,输出一个整数后换行,表示选择某点着陆后,可能访问到的最多的格点数。

 

Sample Input

2
4 3
111
111
111
111
3 3
111
101
111

Sample Output

10
4

HINT

 

题意

 

题解:

记忆化搜索,存一下值就好了

代码:

 

//qscqesze

#include <cstdio>

#include <cmath>

#include <cstring>

#include <ctime>

#include <iostream>

#include <algorithm>

#include <set>

#include <vector>

#include <sstream>

#include <queue>

#include <typeinfo>

#include <fstream>

#include <map>

#include <stack>

typedef long long ll;

using namespace std;

//freopen("D.in","r",stdin);

//freopen("D.out","w",stdout);

#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)

#define maxn 200001

#define mod 10007

#define eps 1e-9

int Num;

char CH[20];

//const int inf=0x7fffffff;   //нчоч╢С

const int inf=0x3f3f3f3f;

/*



inline void P(int x)

{

    Num=0;if(!x){putchar('0');puts("");return;}

    while(x>0)CH[++Num]=x%10,x/=10;

    while(Num)putchar(CH[Num--]+48);

    puts("");

}

*/

//**************************************************************************************

inline ll read()

{

    int x=0,f=1;char ch=getchar();

    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

    return x*f;

}

inline void P(int x)

{

    Num=0;if(!x){putchar('0');puts("");return;}

    while(x>0)CH[++Num]=x%10,x/=10;

    while(Num)putchar(CH[Num--]+48);

    puts("");

}



char s[1001][1001];

int dp[1001][1001][8];

int dx[8]={-1,0,0,1,1,0,0,-1};

int dy[8]={0,1,1,0,0,-1,-1,0};

int n,m;

void dfs(int i,int j,int k)

{

    if(k%2==0)

    {

        if(i+dx[k]<0||i+dx[k]>=n||j+dy[k]<0||j+dy[k]>=m)

            dp[i][j][k]=0;

        else if(s[i+dx[k]][j+dy[k]]=='0')

            dp[i][j][k]=0;

        else

        {

            if(dp[i+dx[k]][j+dy[k]][k+1]==-1)

                dfs(i+dx[k],j+dy[k],k+1);

            dp[i][j][k]=1;

            dp[i][j][k]+=dp[i+dx[k]][j+dy[k]][k+1];

        }

    }

    else

    {

        if(i+dx[k]<0||i+dx[k]>=n||j+dy[k]<0||j+dy[k]>=m)

            dp[i][j][k]=0;

        else if(s[i+dx[k]][j+dy[k]]=='0')

            dp[i][j][k]=0;

        else

        {

            if(dp[i+dx[k]][j+dy[k]][k-1]==-1)

                dfs(i+dx[k],j+dy[k],k-1);

            dp[i][j][k]=1;

            dp[i][j][k]+=dp[i+dx[k]][j+dy[k]][k-1];

        }

    }

}

int main()

{

    int t=read();

    for(int cas=1;cas<=t;cas++)

    {

        n=read(),m=read();

        for(int i=0;i<n;i++)

            for(int j=0;j<m;j++)

                for(int k=0;k<8;k++)

                    dp[i][j][k]=-1;

        for(int i=0;i<n;i++)

            scanf("%s",s[i]);

        int ans2=0;

        for(int i=0;i<n;i++)

        {

            for(int j=0;j<m;j++)

            {

                if(s[i][j]=='0')

                    continue;

                int ans=1;

                if(dp[i][j][0]==-1)

                    dfs(i,j,0);

                ans+=dp[i][j][0];

                if(dp[i][j][2]==-1)

                    dfs(i,j,2);

                ans+=dp[i][j][2];

                if(dp[i][j][4]==-1)

                    dfs(i,j,4);

                ans+=dp[i][j][4];

                if(dp[i][j][6]==-1)

                    dfs(i,j,6);

                ans+=dp[i][j][6];

                ans2=max(ans2,ans);

            }

        }

        printf("%d\n",ans2);

    }

}

 

你可能感兴趣的:(搜索)