2015 UESTC 搜索专题B题 邱老师降临小行星 记忆化搜索
邱老师降临小行星
Time Limit: 20 Sec Memory Limit: 256 MB
题目连接
http://acm.uestc.edu.cn/#/contest/show/61Description
人赢邱老师和任何男生比,都是不虚的。有一天,邱老师带妹子(们)来到了一个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
2
4 3
111
111
111
111
3 3
111
101
111
4 3
111
111
111
111
3 3
111
101
111
Sample Output
10
4
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); } }