luogu P1878 舞蹈课

题目链接:luogu P1878 舞蹈课

题目大意:

题解:
选出所有相邻的异性,将他们存入优先队列中,按照舞蹈技术差值排序,每次选出堆顶的异性对,将答案加上他们的舞蹈技术差值,并标记他们的位置,再寻找离他们最近的没有被选择过的另一对异性,存入优先队列中。

#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
#define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define N 200000 + 10

bool sex[N], vis[N];
string s;
int n, a[N], sum;
vector <pair<int, int> > ans;
struct Node {
	int a, b, w;
	bool operator < (const Node &x) const {
		if (w == x.w) {
			return a > x.a;
		} else {
			return w > x.w;
		}
	}
};
priority_queue <Node> q;

int main() {
	io_speed_up;
	cin >> n;
	cin >> s;
	int len = s.length();
	for (int i = 0; i < len; ++i) {
		if (s[i] == 'G') {
			sex[i + 1] = false;
		} else {
			sex[i + 1] = true;
		}
	}
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
	}
	for (int i = 1; i < n; ++i) {
		if (sex[i] != sex[i + 1]) {
			q.push(Node{i, i + 1, abs(a[i] - a[i + 1])});
		}
	}
	while (!q.empty()) {
		Node temp = q.top();
		q.pop();
		int x = temp.a, y = temp.b;
		if (vis[x] || vis[y])	continue;
		vis[x] = true;
		vis[y] = true;
		sum++;
		ans.push_back(make_pair(x, y));
		while (x > 0 && vis[x])		x--;
		while (y <= n && vis[y])	y++;
		if (x > 0 && y <= n && sex[x] != sex[y]) {
			q.push(Node{x, y, abs(a[x] - a[y])});
		}
	}
	cout << sum << endl;
	for (int i = 0; i < sum; ++i) {
		cout << ans[i].first << ' ' << ans[i].second << endl;
	}
	return 0;
}
posted @ 2020-11-16 20:07  ZZHHOOUU  阅读(142)  评论(0编辑  收藏  举报