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

题目描述

Old MacDonald has a farm and a large potato field, \((10^{10}+1)\times(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;
}
posted @ 2021-01-30 11:33  lrj124  阅读(118)  评论(0编辑  收藏  举报