1. 程式人生 > >Codeforces 848B Rooter's Song(分類+模擬)

Codeforces 848B Rooter's Song(分類+模擬)

continue ++i begin printf oot log http define bool

題目鏈接 Rooter‘s Song

題意 有n個舞者站在x軸上或y軸上,每個人有不同的出發時間。x軸上的舞者垂直x軸正方向移動,y軸上的舞者垂直y軸正方向移動。

當x軸的舞者和y軸的舞者相遇時,他們會互換運動軌跡。求每個舞者的最後位置。

把所有會發生碰撞的舞者塞到一起,按照坐標大小升序排序。

對於某個在x軸上的舞者, 計算他右邊的舞者個數,和他上面的舞者個數(即y軸會和他碰撞的所有舞者個數)

對於某個在y軸上的舞者, 計算他上面的舞者個數,和他右邊的舞者個數(即x軸會和他碰撞的所有舞者個數)

然後根據這些信息計算出每個舞者的碰撞次數,再求出每個舞者最後的位置。

時間復雜度$O(Mlogn)$ $(M = max(w, h))$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

typedef long long LL;

const int N = 4e5 + 10;
const int d = 1e5;

struct node{
	int pos, id;
	friend bool operator < (const node &a, const node &b){
		return a.pos < b.pos;
	}
};

int n, w, h, op, p, t, mx, s;
vector <node> X[N], Y[N];
int flag[N], ans[N], b[N], c[N];

int main(){

	scanf("%d%d%d", &n, &w, &h);
	mx = 0;

	rep(i, 1, n){
		scanf("%d%d%d", &op, &p, &t);
		b[i] = op, c[i] = p;
		if (op == 1) X[p - t + d].push_back({p, i});
		else Y[p - t + d].push_back({p, i});
		mx = max(mx, p - t + d);
	}

	rep(i, 0, mx){
		sort(X[i].begin(), X[i].end());
		sort(Y[i].begin(), Y[i].end());
	}

	rep(i, 0, mx){
		s = (int)X[i].size();
		t = (int)Y[i].size();

		if (s == 0 || t == 0) continue;
		
		rep(j, 0, s - 1){
			int nx  = s - j - 1, ny = t;
			int num;
			if (nx < ny) num = 2 * nx + 1;
			else num = ny * 2;
			if (num & 1) flag[X[i][j].id] = 2; else flag[X[i][j].id] = 1;
			if (flag[X[i][j].id] == 1) ans[X[i][j].id] = X[i][j + num / 2].pos;
			else ans[X[i][j].id] = Y[i][num / 2].pos;
		}

		rep(j, 0, t - 1){
			int nx  = s, ny = t - j - 1;
			int num;
			if (ny < nx) num = 2 * ny + 1;
			else num = nx * 2;
			if (num & 1) flag[Y[i][j].id] = 1; else flag[Y[i][j].id] = 2;
			if (flag[Y[i][j].id] == 2) ans[Y[i][j].id] = Y[i][j + num / 2].pos;
			else ans[Y[i][j].id] = X[i][num / 2].pos;
			
		}
	}

	
	rep(i, 1, n) if (!flag[i]){ flag[i] = b[i];  ans[i] = c[i];}
	rep(i, 1, n) if (flag[i] == 1) printf("%d %d\n", ans[i], h);
			else printf("%d %d\n", w, ans[i]);
	return 0;
}

Codeforces 848B Rooter's Song(分類+模擬)