• 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;
    }
    
  • 相关阅读:
    58. 最后一个单词的长度
    53. 最大子序和
    50. Pow(x, n)
    35. 搜索插入位置
    28. 实现 strStr()
    leetcode 27. 移除元素
    leetcode 26. 删除排序数组中的重复项
    leetcode 21. 合并两个有序链表
    20. 有效的括号
    多线程案例_循环打印_设计4个线程...
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/13986885.html
Copyright © 2020-2023  润新知