社区讨论
只用set实现了前五个样例,其后超时,望大佬以此思路优化时间复杂度
学术版参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @m3edj9zz
- 此快照首次捕获于
- 2024/11/12 19:33 去年
- 此快照最后确认于
- 2025/11/04 14:51 4 个月前
注释很详细,大佬请看
CPP#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <set>
using namespace std;
#define N 200010
pair<int, pair<char, int>> F1;//较小的初始位置和对应的性别与实力
pair<int, pair<char, int>> F2;//较大的
vector<pair<int, pair<char, int>>> R(N);//初始数据读入:初始位置,性别,实力
set<pair<int, pair<char, int>>> r;//维护队列,存储当前在队伍中的人:初始位置,性别,实力
pair<int, pair<int, int>> mid;//处理中间值(需要删除的,添加的,都放在这里,存储内容同M
set<pair<int, pair<int, int>>> M;//当前的:相邻异性的实力差,各自的初始位置
vector<pair<int, int>> ans;//存放答案
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
R[i].first = i;//记录进入队伍的初始位置
cin >> R[i].second.first;//记录性别
}
for (int i = 1; i <= n; i++)
{
cin >> R[i].second.second;//记录实力
}
for (int i = 1; i <= n; i++)
{
r.insert(R[i]);//将数据转读至set进行处理(以初始位置升序)
}
for (int i = 1; i < n; i++)
{
if (R[i].second.first != R[i + 1].second.first)//只要性别不同
{
mid.first = abs(R[i].second.second - R[i + 1].second.second);
mid.second.first = i;
mid.second.second = i + 1;
M.insert(mid);
}
}
while (!M.empty())//空了说明没有相邻异性了
{
auto p = M.begin();//找到当前实力差最小的
ans.push_back({(*p).second.first, (*p).second.second});//记录初始位置
M.erase(*p);//删除这一对
F1.first = ans.back().first;//记录初始位置靠前的人的位置
F1.second.first='A';//'A'比G,B都小,loer_bound处理较方便
auto P1 = lower_bound(r.begin(), r.end(), F1),p1=P1;//获取F1在队列中的指针P1
if (P1 != r.begin())//防止越界,下面同理
{
--p1;//向前判断剔除F1后是否会少一对相邻异性,p1指向前一个人
if ((*(p1)).second.first != (*P1).second.first)//有的话就删掉原先存进M的数据
{
mid.first = abs((*(p1)).second.second - (*P1).second.second);
mid.second.first = (*(p1)).first;
mid.second.second = (*P1).first;
M.erase(mid);
}
}
F2.first = ans.back().second;
F2.second.first='A';
auto P2 = lower_bound(r.begin(), r.end(), F2),p2=P2;
if (P2 != (--r.end()))
{
++p2;//向后剔除
if ((*(p2)).second.first != (*P2).second.first)
{
mid.first = abs((*(p2)).second.second - (*P2).second.second);
mid.second.first = (*P2).first;
mid.second.second = (*(p2)).first;
M.erase(mid);
}
}
if (P2 != (--r.end()) && P1 != r.begin())//是否会产生新的一对相邻异性
{
if ((*(p2)).second.first != (*(p1)).second.first)
{
mid.first = abs((*(p2)).second.second - (*(p1)).second.second);
mid.second.first = (*(p1)).first;
mid.second.second = (*(p2)).first;
M.insert(mid);
}
}
r.erase(*P1);//把人从队列中剔除
r.erase(*P2);
}
cout << ans.size() << endl;//输出答案组数
for (auto it : ans)
{
cout << it.first << " " << it.second << endl;
}
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...