M-SOLUTIONS Programming Contest 2020 F - Air Safety

题目链接
题目描述
在二维平面上给定 n n n个点,每个点有一个移动方向,所有点的速度都为 0.1 0.1 0.1。问相撞的两个点最短时间是多少,若没有两个点相撞就输出 S A F E SAFE SAFE
思路
考虑到有以下几种情况会相撞:右左,上下,右上,右下,左上,左下(右左表示一架飞机向右飞,一架飞机向左飞的情况,以此推类)。
其实就是判断在同一条x轴上的情况,在同一条y轴上的情况,在 y = x + c y=x+c y=x+c上的情况,在 y = − x + c y=-x+c y=x+c上的情况。然后挨个讨论就是了。
不过赛后看了官方题解发现,有一个新的写法可以大大降低代码率。就是把整个状态进行旋转,只要旋转四次,每次状态下只要考虑右左,右上的情况就行了。这可能就是我和巨巨的差距吧。
代码
说明: c a c l 1 ( ) cacl_1() cacl1()计算的是右上的情况, c a c l 2 ( ) cacl_2() cacl2()计算的是右左的情况。 R o t a t e ( ) Rotate() Rotate()表示对当前所有飞机状态的顺时针旋转 90 ° 90° 90°其余的只要暴力就行了。

#include
using namespace std;

const int inf = 0x3f3f3f3f;
const int N = 2e5 + 10;
int x[N], y[N];
char op[N][2];
int n;
vector<pair<int, char> > v1[N << 1];
vector<pair<int, char> > v2[N << 1];

void Rotate() {
	for(int i = 1; i <= n; i++) {
		int xx = y[i], yy = 200000 - x[i];
		char ch = op[i][0];
		if(ch == 'U') ch = 'R';
		else if(ch == 'R') ch = 'D';
		else if(ch == 'D') ch = 'L';
		else ch = 'U';
		x[i] = xx, y[i] = yy, op[i][0] = ch;
	}
}

int cacl1() {
	for(int i = 0; i < N * 2; i++) v1[i].clear();
	int res = inf;
	for(int i = 1; i <= n; i++) {
		if(!(op[i][0] == 'R' || op[i][0] == 'U')) continue;
		v1[x[i] + y[i]].push_back({x[i], op[i][0]});
	}
	for(int i = 0; i < N * 2; i++) {
		sort(v1[i].begin(), v1[i].end());
		for(int j = 0; j < (int)v1[i].size() - 1; j++) {
			if(!(v1[i][j].second == 'R' && v1[i][j + 1].second == 'U')) continue;
			res = min(res, v1[i][j + 1].first - v1[i][j].first);
		}
	}
	if(res == inf) return inf;
	return res * 10;
}

int cacl2() {
	for(int i = 0; i < N * 2; i++) v2[i].clear();
	int res = inf;
	for(int i = 1; i <= n; i++) {
		if(!(op[i][0] == 'R' || op[i][0] == 'L')) continue;
		v2[y[i]].push_back({x[i], op[i][0]});
	}
	for(int i = 0; i < N * 2; i++) {
		sort(v2[i].begin(), v2[i].end());
		for(int j = 0; j < (int)v2[i].size() - 1; j++) {
			if(!(v2[i][j].second == 'R' && v2[i][j + 1].second == 'L')) continue;
			res = min(res, v2[i][j + 1].first - v2[i][j].first);
		}
	}
	if(res == inf) return inf;
	return res * 5;
}

void solve() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		scanf("%d%d%s", &x[i], &y[i], &op[i]);
	}
	int res = inf;

	for(int i = 1; i <= 4; i++) {
		res = min(res, cacl1());
		res = min(res, cacl2());
		Rotate();
	}
	if(res == inf) puts("SAFE");
	else printf("%d\n", res);
}

int main() {
//    freopen("in.txt", "r", stdin);
	solve();
	return 0;
}

你可能感兴趣的:(AtCoder)