意甲冠军:
薛期呵和王熙凤不想很接近生活(因为假定他们一起,柴可能取代王熙凤)
现在'.'事情是这样的。'#'一堵墙。薛期呵对宝让生活远;
因此,选择一个最长的公路,让他们住在两端;
路达一个转折点。它是90;
像以下这张图:
#.#
##.
..#
最长的路是(图中*的位置)
#*#
##*
.*# 长度为3;
思路:
计算出每一个点在八个方向上的长度。
然后在把每一个点垂直两个方向的距离加起来(一个点有8种加法)
取全部点的最大值;
计算时,由于假设要算这个点 左上方 延伸多长,就要算算它左上方那个点能延伸多长,再加1(所以这时候左上方那个点必须已经算出来了)。
而要计算这个点 右下方 延伸多长,也是同理要先算出它右下方那个点;
所以有四个方向要从上往下遍历。
另外四个方向从下往上遍历;
AC代码:
#include<cstdio> #include<cstring> #include<queue> using namespace std; const int N = 105; char g[N][N]; int n; int dir[8][2] = {{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1}}; int dp[N][N][8]; int main() { while(scanf("%d",&n) && n) { memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) { getchar(); for(int j = 1; j <= n; j++) { scanf("%c",&g[i][j]); if(g[i][j] == '.') { for(int k = 0; k < 8; k++) { dp[i][j][k] = 1; } } } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(g[i][j] == '#') continue; for(int k = 0; k < 4; k++) { int x = i + dir[k][0]; int y = j + dir[k][1]; if(x > 0 && y > 0 && x <= n && y <= n && g[x][y] != '#') { dp[i][j][k] += dp[x][y][k]; } } } } for(int i = n; i >= 1; i--) { for(int j = n; j >= 1; j--) { if(g[i][j] == '#') continue; for(int k = 4; k < 8; k++) { int x = i + dir[k][0]; int y = j + dir[k][1]; if(x > 0 && y > 0 && x <= n && y <= n && g[x][y] != '#') { dp[i][j][k] += dp[x][y][k]; } } } } int m = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { for(int k = 0; k < 8; k++) { if(dp[i][j][k] + dp[i][j][(k + 2)%8] > m) m = dp[i][j][k] + dp[i][j][(k + 2)%8]; } } } printf("%d ",m - 1); } }
版权声明:本文博客原创文章,博客,未经同意,不得转载。