【CF243C】Colorado Potato Beetle - 離散化+搜索

題目描述

Old MacDonald has a farm and a large potato field, \((10^{10}+1)×(10^{10}+1)\) square meters in size. The field is divided into square garden beds, each bed takes up one square meter.
Old McDonald knows that the Colorado potato beetle is about to invade his farm and can destroy the entire harvest. To fight the insects, Old McDonald wants to spray some beds with insecticides.
So Old McDonald went to the field, stood at the center of the central field bed and sprayed this bed with insecticides. Now he's going to make a series of movements and spray a few more beds. During each movement Old McDonald moves left, right, up or down the field some integer number of meters. As Old McDonald moves, he sprays all the beds he steps on. In other words, the beds that have any intersection at all with Old McDonald's trajectory, are sprayed with insecticides.
When Old McDonald finished spraying, he wrote out all his movements on a piece of paper. Now he wants to know how many beds won't be infected after the invasion of the Colorado beetles.
It is known that the invasion of the Colorado beetles goes as follows. First some bed on the field border gets infected. Than any bed that hasn't been infected, hasn't been sprayed with insecticides and has a common side with an infected bed, gets infected as well. Help Old McDonald and determine the number of beds that won't be infected by the Colorado potato beetle.

題目大意

有一個 \((10^{10}+1)×(10^{10}+1)\) 的正方形網格,從最中間開始,按照給定的指令上下左右走,走過的格子或者被圈起來的格子不能到達,問有多少格子不能到達。

思路

注意 \(n\) 的範圍很小,所以把指令看成是線段,將所有線段的端點離散化,注意要將 \(x,x-1,x+1\) 都離散化然後來染色,最後按離散化前的邊長大小統計計算。

#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 3000 + 10;
int n,nowx,nowy,ax[maxn],ay[maxn],px[maxn],py[maxn],col[maxn][maxn];
long long ans;
inline void add(int x,int y) {
	ax[++ax[0]] = x-1; ax[++ax[0]] = x+1; ax[++ax[0]] = x;
	ay[++ay[0]] = y-1; ay[++ay[0]] = y+1; ay[++ay[0]] = y;
}
inline int xash(int x) { return lower_bound(ax+1,ax+ax[0]+1,x)-ax+1; }
inline int yash(int y) { return lower_bound(ay+1,ay+ay[0]+1,y)-ay+1; }
inline void dfs(int x,int y) {
	if (x < 1 || x > ax[0]+1 || y < 1 || y > ay[0]+1 || col[x][y]) return;
	col[x][y] = 2;
	dfs(x+1,y); dfs(x,y+1); dfs(x-1,y); dfs(x,y-1);
}
int main() {
	scanf("%d\n",&n);
	add(nowx,nowy);
	for (int i = 1,len;i <= n;i++) {
		char ch;
		scanf("%s%d",&ch,&len);
		if (ch == 'R') nowy += len;
		if (ch == 'L') nowy -= len;
		if (ch == 'U') nowx += len;
		if (ch == 'D') nowx -= len;
		px[i] = nowx;
		py[i] = nowy;
		add(nowx,nowy);
	}
	sort(ax+1,ax+ax[0]+1); ax[0] = unique(ax+1,ax+ax[0]+1)-(ax+1);
	sort(ay+1,ay+ay[0]+1); ay[0] = unique(ay+1,ay+ay[0]+1)-(ay+1);
	for (int i = 1;i <= n;i++) {
		int sx = xash(px[i-1]),sy = yash(py[i-1]),ex = xash(px[i]),ey = yash(py[i]);
		if (sx == ex) for (int j = min(sy,ey);j <= max(sy,ey);j++) col[sx][j] = 1;
		if (sy == ey) for (int j = min(sx,ex);j <= max(sx,ex);j++) col[j][sy] = 1;
	}
	dfs(1,1);
	for (int i = 1;i <= ax[0];i++)
		for (int j = 1;j <= ay[0];j++)
			if (col[i][j] ^ 2) ans += 1ll*(ax[i]-ax[i-1])*(ay[j]-ay[j-1]);
	printf("%lld",ans);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章