CodeForces 45C Dancing Lessons

本文深入探讨了深度学习技术在音视频处理、AR特效、AI音视频处理等领域的应用,包括图像处理、音视频直播流媒体、音视频编解码算法等关键技术和实践案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接: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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值