舞蹈课
题目描述
有
n
n
n 个人参加一个舞蹈课。每个人的舞蹈技术由整数来决定。在舞蹈课的开始,他们从左到右站成一排。当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞。如果不止一对,那么最左边的那一对出列。一对异性出列之后,队伍中的空白按原顺序补上(即:若队伍为 ABCD
,那么 BC
出列之后队伍变为 AD
)。舞蹈技术相差最小即是
a
i
a_i
ai 的绝对值最小。
任务是模拟以上过程,确定跳舞的配对及顺序。
输入格式
第一行一个正整数 n n n 表示队伍中的人数。
第二行包含
n
n
n 个字符 B
或者 G
,B
代表男,G
代表女。
第三行为 n n n 个整数 a i a_i ai。所有信息按照从左到右的顺序给出。
输出格式
第一行一个整数表示出列的总对数 k k k。
接下来 k k k 行,每行是两个整数。按跳舞顺序输出,两个整数代表这一对舞伴的编号(按输入顺序从左往右 1 1 1 至 n n n 编号)。请先输出较小的整数,再输出较大的整数。
样例 #1
样例输入 #1
4
BGBG
4 2 4 3
样例输出 #1
2
3 4
1 2
提示
对于 50 % 50\% 50% 的数据, 1 ≤ n ≤ 200 1\leq n\leq 200 1≤n≤200。
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 2 × 1 0 5 1\leq n\leq 2\times 10^5 1≤n≤2×105, 1 ≤ a i ≤ 1 0 7 1\le a_i\le 10^7 1≤ai≤107。
题意:
如题。
思路:
题目要求绝对值相差最小的一对异性出列,观察数据范围,显然要用到优先队列控制时间复杂度。
且题目要求对原序列进行删除和拼接,考虑用双链表实现这一点(时间复杂度 O(1)
)
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
#define x first
#define y second
const int N = 2e5 + 10;
int n;
string qu;
int a[N];
bool st[N];
int e[N], l[N], r[N], idx;
//初始化
void init()
{
l[1] = 0, r[0] = 1;//初始化 第一个点的右边是 1 第二个点的左边是 0
idx = 2;//idx 此时已经用掉两个点了
}
//在第 K 个点右边插入一个 X
void add(int k, int x)
{
e[idx] = x;
l[idx] = k;
r[idx] = r[k]; //todo 这边的 k 不加 1 , 输入的时候 k+1 就好
l[r[k]] = idx;
r[k] = idx;
idx++;
}//当然在K的左边插入一个数 可以再写一个,也可以直接调用我们这个函数,在k的左边插入一个 数,等价于在l[k]的右边插入一个数add(l[k],x)
//*删除第k个点
void remove(int k)
{
r[l[k]] = r[k];
l[r[k]] = l[k];
}
struct node
{
int idx1, idx2;
int dif;
bool operator< (const node& x)const {
if (dif == x.dif) return idx1 > x.idx1;
return dif > x.dif;
}
};
signed main()
{
int T = 1; //cin >> T;
while (T--)
{
init();
cin >> n >> qu;
qu = " " + qu;
for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]), add(i, a[i]);
priority_queue<node> heap;
for (int i = 1; i <= n - 1; ++i)
{
if (qu[i] != qu[i + 1])
{
heap.push({ i, i + 1, abs(a[i] - a[i + 1]) });
}
}
int k = 0;
vector<pii> ans;
while (heap.size())
{
auto t = heap.top(); heap.pop();
if (st[t.idx1] || st[t.idx2]) continue;
++k;
ans.push_back({ t.idx1, t.idx2 });
if (l[t.idx1] && r[t.idx2] != (n + 1) && qu[l[t.idx1]] != qu[r[t.idx2]])
{
heap.push({ l[t.idx1], r[t.idx2], abs(a[l[t.idx1]] - a[r[t.idx2]]) });
}
remove(t.idx1), remove(t.idx2);
st[t.idx1] = st[t.idx2] = true;
}
cout << k << '\n';
for (auto v : ans)
{
printf("%lld %lld\n", v.x, v.y);
}
}
return 0;
}