AtCoder Grand Contest 044 B Joker

题意:
电影院放映结束,场地为 n ∗ n n*n nn的矩阵,且每个位置上都有人.
一个人离场时,只有他一个人能移动,假如他碰到了别人的位置,别人就会生气.
一个人只有离开 n ∗ n n*n nn的矩阵,即到达边界才算离场完毕.
现在,给出一个离场顺序,求出生气人次的最小值.

d [ x ] [ y ] d[x][y] d[x][y]表示 x 行 , y 列 x行,y列 x,y的人当前的最少得罪人数量.
初始时,显然 d [ x ] [ y ] = min ⁡ { x − 1 , n − x , y − 1 , n − y } d[x][y]=\min\{x-1,n-x,y-1,n-y\} d[x][y]=min{x1,nx,y1,ny}.

然后,每次一个人离开后暴力松弛这个最短路.
因为初始的 ∑ d [ x ] [ y ] ≈ n 3 / 6 \sum d[x][y]\approx n^3/6 d[x][y]n3/6,所以复杂度正确,可以轻松跑过.
证明:
AtCoder Grand Contest 044 B Joker_第1张图片
我们明显可以把这个图分割成8块,所以我们只要求一块的答案即可.

AtCoder Grand Contest 044 B Joker_第2张图片
x = n / 2 x=n/2 x=n/2,然后我们要求 ∑ i = 1 x i ( x − i ) ≈ x ∗ x 2 / 2 − x 3 / 3 = 1 48 n 3 , s o ∑ d [ x ] [ y ] ≈ 1 6 n 3 \sum_{i=1}^x i(x-i)\approx x*x^2/2-x^3/3=\dfrac {1}{48}n^3,so \sum d[x][y]\approx \dfrac 1 6 n^3 i=1xi(xi)xx2/2x3/3=481n3,sod[x][y]61n3,

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define lc (x<<1)
#define rc (x<<1|1)
#define gc getchar()
#define mk make_pair
#define pi pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=510;
template<class o>void qr(o&x) {
	char c=gc;int f=1;x=0;
	while(!isdigit(c)){if(c=='-')f=-1;c=gc;}
	while(isdigit(c))x=x*10+c-'0',c=gc;
	x*=f;
}
template<class o>void qw(o x) {
	if(x/10)qw(x/10);
	putchar(x%10+'0');
}
template<class o> void pr1(o x) {
	if(x<0)x=-x,putchar('-');
	qw(x); putchar(' ');
}
template<class o>void pr2(o x) {
	if(x<0)x=-x,putchar('-');
	qw(x);puts("");
}

int n,d[N][N],ans;
bool f[N][N];

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

void dfs(int x,int y) {
	for(int t=0;t<4;t++) {
		int tx=x+dx[t],ty=y+dy[t];
		if(tx&&tx<=n&&ty&&ty<=n&&d[tx][ty]>d[x][y]+f[x][y]) {
			d[tx][ty]=d[x][y]+f[x][y];
			dfs(tx,ty);
		}
	}
}

int main() {
	qr(n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			ans+=(d[i][j]=min(min(i-1,n-i),min(j-1,n-j)));
	ans=0; memset(f,1,sizeof f);
	for(int i=1,t,x,y;i<=n*n;i++) {
		qr(t); x=(t-1)/n+1; y=t-(x-1)*n;
		ans+=d[x][y];f[x][y]=0; dfs(x,y);
	}
	pr2(ans);
	return 0;
}

你可能感兴趣的:(AtCoder Grand Contest 044 B Joker)