一道好枚举+模拟题目。转换思维视角
这道题是我做的,规模不大N<=100,以为正常DFS搜索,于是傻乎乎的写了起来。各种条件限制模拟过程
但仔细一分析发现对每个点进行全部八个方向的遍历100X100X100^8 。100X100个点,每个点在走的时候8中选择,TLE
于是改为另一个角度:
以符合要求的点为拐弯点,朝两个垂直的方向走,求出最远的距离。这样只要对每个点各个方向的长度知道,组合一下对应的就OK。
避免了每个点深搜。
PS:搜索的时候x,y写反了,导致构图出现问题,以后用[dy][dx]表示位置,前列后行变化。搜索时标记为最好写在函数开头结尾,适应于复杂情况
#include <stdio.h>
#include <string.h>
#include<iostream>
using namespace std;
#define mem(a) memset(a,0,sizeof(a))
#define max(a,b) (a)>(b)?(a):(b)
typedef __int64 LL;
const LL maxn=10+100;
int maps[maxn][maxn];
int vis [maxn][maxn];
int N,M,T;
int dt[][2]={{0,-1}, {1,-1}, {1,0} , {1,1}, {0,1}, {-1,1}, {-1,0}, {-1,-1}};
int step[8];
int IsInBord(int x,int y)
{
if(x<0 || x>=N || y<0 || y>=N)
return 0;
return 1;
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("in.txt","r",stdin);
#endif
int i,j,k;
char str[100];
while(scanf("%d",&N),N)
{
getchar();
mem(maps);
for(i=0;i<N;i++)
{
gets(str);
int len=strlen(str);
for(j=0;j<len;j++)
{
if(str[j]=='.')
maps[i][j]=1;
}
}
int ans=0;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(maps[i][j]==0 )
continue;
int ai, aj;
for(k = 0; k < 8;k++)
{
step[k] = 0;
ai = i + dt[k][1];
aj = j + dt[k][0];
//cout<<"k"<<k<<","<<dt[k][1]<<","<<dt[k][0]<<endl;
while(IsInBord(ai, aj) && maps[ai][aj] == 1)
{
step[k]++;
ai += dt[k][1];
aj += dt[k][0];
//cout<<ai<<","<<aj<<","<<maps[ai][aj]<<endl;
}
}
int res = 0;
for(k = 0; k < 8; k++)
{
if(step[k] + step[(k + 2) % 8] + 1 > res)
{
res = step[k] + step[(k + 2) % 8] + 1;
}
}
ans = max(res, ans);
}
printf("%d\n",ans);
}
return 0;
}