【HDU5725 2016 Multi-University Training Contest 1C】【最短路 曼哈顿距离+贪心 前缀和】Game 有特殊守卫地图中所有空格点的最短路之和

Game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 362    Accepted Submission(s): 88


Problem Description
  Sea5 and wzh are playing games.

  There are some guards on an n × m chessboard. Every guard can attack eight cells around him and release shockwave to attack the whole row and column where he stand.

  Sea5 and wzh are at the beginning stage of the game, they have already put some guards on the chess cells. No guards can be attacked by another guard right now. So they all fell asleep.

  An innocent passer-by is on the chessboard. He can move to up, down, left or right from where he stands. The guards won’t attack him unless the passer-by move to where they stand. The innocent man may appear at any point on the chessboard and move to any point.

  The innocent passer-by wants to know the average shortest distance of all the ways he can move without attacked by guards.
 

Input
  Multiple test cases.

  The first line is an integer   T(T50), the number of cases.

  For each case, first line is two integers   n  and   m(2n,m,1000).  

  The next   n  lines contain   m  symbols indicate the cells of chessboard. ‘G’ indicates a guard and ‘#’ indicates an empty cell.
 

Output
  One line per case, shortest distance of all the ways the passer-by can move without attacked by guards.

  Round the answer to four decimals.
 

Sample Input
 
   
1 2 2 ## G#
 

Sample Output
 
   
0.8889
Hint
Ways of distance 0: 3 Ways of distance 1: 4 Ways of distance 2: 2 The answer is (3 * 0 + 1 * 4 + 2 * 2) / (3 + 4 + 2)
 

Author
HIT
 

Source
2016 Multi-University Training Contest 1

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template inline void gmin(T1 &a, T2 b) { if (b Y[i])*beh + (m - Y[i]);
				ans += bef * beh * 4;
			}
		}
		bef = beh = 0;
		for (int i = 1; i <= m; ++i)
		{
			if (!X[i])bef = beh = 0;
			else
			{
				bef = (X[i - 1] && X[i - 1] < X[i])*bef + (X[i] - 1);
				beh = (X[i - 1] > X[i])*beh + (n - X[i]);
				ans += bef * beh * 4;
			}
		}
		printf("%.4f\n", ans / (tot * tot * 1.0));
	}
	return 0;
}
/*
【trick&&吐槽】
这题是上一场多校唯一没有读的题,但似乎并不是很难?
果然不难。TwT 。多读题、敢开题,非常重要。

【题意】
给你一个n*m(1000*1000)的棋盘,有若干守卫'G',其余位置为空地'#'。
对于每个守卫,可以攻击到——
1,周围8个点
2,同行或同列的点
这些守卫之间无法相互攻击到。
问你,所有空地之间最短路的距离之和是多少(最短路不允许经过'G'点)

【类型】
最短路 脑洞

【分析】
这种乱搞题我竟然没有发现,我是大傻逼啊。
首先,我们发现我们不允许经过'G'点,而'G'点之间又有着之间相互攻击不到的关系。

思考:
地图大小太大,我们做最短路是吃不消的。
于是两点之间的最短路,应该有更快的计算方式。
猜想——两点之间的最短路,是否为这两点间的曼哈顿距离呢?
显然不一定是。
然而,我们研究这个地图,两点之间的最短路,有怎样的规律呈现呢?    

1,最多只会因为格子的阻挡走一次弯路。
2,走一次弯路的条件是——
	(1),同行同列
	(2),非同行同列,但被阶梯型阻挡。

这个阶梯型阻挡很有特点,我们可以通过前缀和更新答案。
然后问题情况就变得很简单。

于是——
对于这道题而言——
曼哈顿距离预处理+前缀和更新阻挡情况=AC

【时间复杂度&&优化】
O(nm)

【数据】
input
100
5 5
####G
G####
##G##
#####
#G###
*/


你可能感兴趣的:(题库-HDU,图论-最短路,贪心,数据结构-前缀和)