CodeForces 45C Dancing Lessons

链接:http://codeforces.com/problemset/problem/45/C


Dancing Lessons

time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

There are n people taking dancing lessons. Every person is characterized by his/her dancing skill ai. At the beginning of the lesson they line up from left to right. While there is at least one couple of a boy and a girl in the line, the following process is repeated: the boy and girl who stand next to each other, having the minimal difference in dancing skills start to dance. If there are several such couples, the one first from the left starts to dance. After a couple leaves to dance, the line closes again, i.e. as a result the line is always continuous. The difference in dancing skills is understood as the absolute value of difference of ai variable. Your task is to find out what pairs and in what order will start dancing.


Input

The first line contains an integer n (1 ≤ n ≤ 2·105) — the number of people. The next line contains n symbols B or G without spaces. B stands for a boy, G stands for a girl. The third line contains n space-separated integers ai (1 ≤ ai ≤ 107) — the dancing skill. People are specified from left to right in the order in which they lined up.

Output

Print the resulting number of couples k. Then print k lines containing two numerals each — the numbers of people forming the couple. The people are numbered with integers from 1 to n from left to right. When a couple leaves to dance you shouldn't renumber the people. The numbers in one couple should be sorted in the increasing order. Print the couples in the order in which they leave to dance.


Sample test(s)

Input

4
BGBG
4 2 4 3


Output
2
3 4
1 2


Input
4
BBGG
4 6 1 5


Output
2
2 3
1 4


Input
4
BGBB
1 1 2 3


Output
1
1 2


大意——有n个人在上舞蹈课,每个人都有相应的舞蹈技能。开始上课时,他们是从左到右排成一行。队伍中至少有一对男女站在一起,接下来就重复一个操作直至不满足条件:找到一对站在一起的男女,使得他们的舞蹈技能差值极小,然后开始跳舞。存在多个的话,那么就从左边的开始。抽走一对后,队伍合并。问:总共有多少对在跳舞,并且按顺序输出跳舞成员,即每对的成员标号。


思路——挑选有优先顺序,那么可以用优先队列来进行挑选;最后输出也有顺序,并且还要知道跳舞对数,那么可以用vector容器在挑选时进行存储。最后只要输出容器存储大小及其里面存储的元素即可。


复杂度分析——时间复杂度:O(n),空间复杂度:O(n)


附上AC代码:


#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <map>
using namespace std;
typedef unsigned int UI;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
const double pi = acos(-1.0);
const double e = exp(1.0);
const int maxn = 200005;
char str[maxn]; // 队列顺序
int skill[maxn]; // 舞蹈技巧
int prev[maxn], next[maxn]; // 某一个人的前后是谁
bool flag[maxn]; // 标记某一个人是否被访问
struct dance
{
	int left, right, diff;
	bool operator < (const dance & p) const{
		return diff==p.diff ? left>p.left : diff>p.diff;
	} // 按照技巧差距大小进行排列,相同按左边的大小排列
};
priority_queue<dance> que; // 创立一个优先队列
vector<pair<int, int> > order; // 创立一个数对集合

int main()
{
	ios::sync_with_stdio(false);
	int n;
	while (scanf("%d", &n) != EOF)
	{
		//while (!que.empty())
			//que.pop();
		order.clear(); // 清空容器中的数据
		scanf("%s", str+1); // 输入队列顺序
		for (int i=1; i<=n; i++)
		{
			scanf("%d", skill+i); // 输入技能并记录左右
			prev[i] = i-1;
			next[i] = i+1;
		}
		dance temp;
		for (int i=1; i<n; i++)
			if (str[i] != str[i+1])
			{ // 找舞伴并记录技能差距
				temp.left = i;
				temp.right = i+1;
				temp.diff = abs(skill[i]-skill[i+1]);
				que.push(temp);
			}
		memset(flag, 0, sizeof(flag)); // 标记归位
		while (!que.empty())
		{
			temp = que.top();
			que.pop();
			if (flag[temp.left] || flag[temp.right])
				continue; // 判断是否检查过
			order.push_back(make_pair(temp.left, temp.right)); // 没检查过,放入集合中
			int _left = prev[temp.left]; // 合并队伍
			int _right = next[temp.right];
			flag[temp.left] = flag[temp.right] = 1; // 标记被检查的
			next[_left] = _right;
			prev[_right] = _left;
			if (_left<1 || _right>n)
				continue; // 检查是否不在队伍中
			if (str[_left] != str[_right]) // 判断是否有新的舞伴
			{
				temp.left = _left;
				temp.right = _right;
				temp.diff = abs(skill[_left]-skill[_right]);
				que.push(temp);
			}
		}
		printf("%d\n", order.size()); // 输出舞伴的对数
		for (int i=0; i<order.size(); i++) // 输出舞伴组合
			printf("%d %d\n", order[i].first, order[i].second);
	}
	return 0;
}


你可能感兴趣的:(优先队列,codeforces)