codeforces 45c dancing lessons(优先队列)

来源:互联网 发布:snmp监控linux主机 编辑:程序博客网 时间:2024/06/15 23:37

点我看题

题意:给你已经站成一排的dancers的性别,每个dancer对应一个技能值,不同性别可以一起dance,每个dancer首先选择的只能是与自己相邻的dancer,其次如果它的左右两变与自己的性别都不同,那么选择技能值的差较小的那个,如果技能差相等,选择靠左的那个.

分析:用优先队列解,首先让所有的当前可能的情况入队,然后让最小的出队,再看有没有新的dancer可以组队,同时更新左右相邻位置.

参考代码:

#include<cstdio>#include<cmath>#include<cstring>#include<queue>#include<algorithm>#include<iostream>using namespace std;const int maxn = 2e5+5;int n;char arr[maxn];//记录int val[maxn];//对应技能值int l[maxn],r[maxn];//左右的编号struct Node{int now,next;int dis;bool operator < ( const Node &a) const//重载小于号{if( dis != a.dis)return dis > a.dis;return now > a.now;}};priority_queue<Node> q;//结构体的优先队列bool vis[maxn];int main(){while( cin >> n){cin >> arr+1;int cnt = 0;for( int i = 1; i <= n; i++){l[i] = i-1;r[i] = i+1;if( arr[i] == 'B')cnt++;cin >> val[i];}cnt = min(cnt,n-cnt);while( !q.empty())q.pop();for( int i = 1; i < n; i++){if( arr[i] != arr[i+1]){Node tmp;tmp.now = i;tmp.next = i+1;tmp.dis = abs(val[i]-val[i+1]);q.push(tmp);}}memset(vis,false,sizeof(vis));cout << cnt << endl;while( cnt--){Node tmp;while( !q.empty()){tmp = q.top();q.pop();if( !vis[tmp.now] && !vis[tmp.next]){cout << tmp.now << " "<< tmp.next << endl;vis[tmp.now] = vis[tmp.next] = true;break;}}int lc = l[tmp.now];int rc = r[tmp.next];r[lc] = rc;l[rc] = lc;tmp.now = lc;tmp.next = rc;tmp.dis = abs(val[lc]-val[rc]);if( lc > 0 && rc <= n && arr[lc] != arr[rc])q.push(tmp);}}return 0;}