Submission #1327070

#TimeUsernameProblemLanguageResultExecution timeMemory
1327070trideserNaval battle (CEOI24_battle)C++20
6 / 100
3095 ms42892 KiB
#include <bits/stdc++.h>
using namespace std;

#define col tuple<int, int, int>
const tuple<int, int, int> NTP = make_tuple(-1, 0, 0);

int n;
vector<set<tuple<int, int, int>>> rows(16);
vector<int> dirmap = {0, 1, 2, 1,  -1, 0, 1, 2,  -2, -1, 0, -1,  -1, -2, 1, 0};
vector<tuple<int, int, int>> ships;

col get_collision(int shipid, int dir) {
	int x, y, d;
	tie(x, y, d) = ships[shipid];
	int dirid = 4 * d + dir;
	if(dirmap[dirid] == 0) return NTP;
	//cout << dirid << " " << x << "\n";
	if(dirmap[dirid] == 1) {
		int posid = ((d ^ 0x1) == dir) ? x + y : x - y;
		auto it = rows[dirid].upper_bound(make_tuple(posid, x, -1));
		if(it == rows[dirid].end()) return NTP;
		tuple<int, int, int> t = *it;
		if(get<0>(t) != posid) return NTP;
		//cout << "COLLISION: " << shipid << " " << get<2>(t) << "\n";
		return make_tuple(abs(x - get<1>(t)), shipid, get<2>(t));
	}
	/*
	if(dirmap[dirid] == -1) {
		int posid = ((d ^ 0x1) == dir) ? x + y : x - y;
		auto it = rows[dirid][posid].lower_bound(x);
		if(it == rows[dirid][posid].begin()) return NTP;
		--it;
		//cout << "COLLISION: " << shipid << " " << it->second << " " << d << " " << dir << "\n";
		return make_tuple(abs(x - it->first), shipid, it->second);
	}*/
	if(dirmap[dirid] == 2) {
		int posid = y;
		int pos2 = x;
		if(d == 1) {
			posid = x;
			pos2 = y;
		}
		auto it = rows[dirid].upper_bound(make_tuple(posid, pos2, -1));
		if(it == rows[dirid].end()) return NTP;
		tuple<int, int, int> t = *it;
		if(get<0>(t) != posid) return NTP;
		//cout << "COLLISION: " << shipid << " " << it->second << "\n";
		return make_tuple(abs(pos2 - get<1>(t)), shipid, get<2>(t));
	}
	return NTP;
}

int main() {
	cin >> n;
	for(int i = 0; i < n; i++) {
		int x, y;
		char ch;
		cin >> x >> y >> ch;
		int dir = 0;
		if(ch == 'N' || ch == 'W') dir |= 2;
		if(ch == 'S' || ch == 'N') dir |= 1;
		//cout << dir << " " << dir + 4 * (dir ^ 0x1) << "\n";
		rows[dir + 4 * (dir ^ 0x1)].insert(make_tuple(x + y, x, i));
		rows[dir + 4 * (3 - dir)].insert(make_tuple(x - y, x, i));
		if(dir & 0x1)
			rows[dir + 4 * (dir ^ 0x2)].insert(make_tuple(x, y, i));
		else
			rows[dir + 4 * (dir ^ 0x2)].insert(make_tuple(y, x, i));
		ships.push_back(make_tuple(x, y, dir));
	}
	/*
	for(int i = 0; i < 16; i++) {
		cout << "i: " << i << "\n";
		for(tuple<int, int, int> t : rows[i]) {
			cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << "\n";
		}
	}*/
	vector<bool> alive(n, true);
	priority_queue<col, vector<col>, greater<col>> q;
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < 4; j++) {
			col c = get_collision(i, j);
			if(c == NTP) continue;
			//cout << "A";
			q.push(c);
		}
	}
	int lastt = -1;
	vector<int> to_remove;
	while(!q.empty()) {
		assert(q.size() < 1e6);
		if(get<0>(q.top()) != lastt) {
			for(int a : to_remove) {
				alive[a] = false;
				int x, y, dir;
				tie(x, y, dir) = ships[a];
				rows[dir + 4 * (dir ^ 0x1)].erase(make_tuple(x + y, x, a));
				rows[dir + 4 * (3 - dir)].erase(make_tuple(x - y, x, a));
				if(dir & 0x1)
					rows[dir + 4 * (dir ^ 0x2)].erase(make_tuple(x, y, a));
				else
					rows[dir + 4 * (dir ^ 0x2)].erase(make_tuple(y, x, a));
			}
			lastt = get<0>(q.top());
		}
		int t, id1, id2;
		tie(t, id1, id2) = q.top();
		q.pop();
		//cout << "Q: " << t << " " << id1 << " " << id2 << "\n";
		if(alive[id1] && alive[id2]) {
			//cout << "\tX\n";
			to_remove.push_back(id1);
			to_remove.push_back(id2);
		}
		else if(alive[id1]) {
			col c = get_collision(id1, get<2>(ships[id2]));
			if(c != NTP) q.push(c);
		}
		else if(alive[id2]) {
			col c = get_collision(id2, get<2>(ships[id1]));
			if(c != NTP) q.push(c);
		}
	}
	for(int a : to_remove) {
		alive[a] = false;
	}
	for(int i = 0; i < n; i++) {
		if(alive[i]) cout << i + 1 << "\n";
	}
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...