【2022杭电多校】第六场 Loop 【使用数据结构模拟】
链接
https://acm.hdu.edu.cn/showproblem.php?pid=7208
题意是说给你一个序列,你需要做exactly k次操作,每次操作选择一个区间[l,r],你可以将l位置的数移动到r位置,同时区间内的其他所有数左移一位
问你经过k次操作后能得到的字典序最大的数列是什么
思路
贪心!
思路1
每次找出\(a_i>a_{i-1}\)的\(a_{i-1}\),将它拿出序列,放进一个优先队列中,此为一次操作,重复k次
注意不要k次暴力for查找,会超时,此处应用栈这个数据结构 细节见代码
View Code
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int N = 3e5+10;
int t,n,k;
int a[N];
int s[N];
int top;
int main(){
int t; scanf("%d",&t);
while(t--){
top=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
priority_queue<int>q;
for(int i=1;i<=n;i++){
while(top && s[top]<a[i] && k){
q.push(s[top]);
top--;
k--;
}
s[++top]=a[i];
}
vector<int>ans;
for(int i=1;i<=top;i++){
while(!q.empty() && q.top()>s[i]){
ans.push_back(q.top());
q.pop();
}
ans.push_back(s[i]);
}
while(!q.empty()){
ans.push_back(q.top());
q.pop();
}
for(int i=0;i<ans.size();i++){
if(i==0) printf("%d",ans[i]);
else printf(" %d",ans[i]);
}puts("");
}
system("pause");
return 0;
}
思路2
定义一个结构体<value,position>,按照升序顺序存进set,每次从set尾部拿出一个元素,如果它可以移动到最前面来,那就可以一位一位移;如果不能就继续在set里找可以移动的最大的元素。
View Code
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int N = 3e5+10;
int t,n,k;
int a[N];
bool valid[N];
set<pii>st,q;
vector<int>ans;
int main(){
int t; scanf("%d",&t);
while(t--){
st.clear();
q.clear();
ans.clear();
int mxid=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
st.insert({a[i],i});
valid[i]=0;
if(i<=k+1&&a[i]>a[mxid]) mxid=i;
}
int ind=mxid;
k-=(ind-1);
valid[mxid]=1;
for(int i=1;i<mxid;i++) q.insert({a[i],i});
while(!st.empty()){
if(k==0) break;
auto now=*--st.end();
int dis=now.second-1-ind;
if(dis>=0 && k>=dis){
valid[now.second]=1;
for(int i=ind+1;i<now.second;i++){
q.insert({a[i],i});
}
k-=dis;
ind=now.second;
}
st.erase(now);
}
for(int i=ind+1;i<=n;i++) valid[i]=1;
for(int i=1;i<=n;i++){
if(valid[i]){
while(!q.empty()&&(*--q.end()).first>a[i]){
ans.push_back((*--q.end()).first);
q.erase(*--q.end());
}
ans.push_back(a[i]);
}
}
while(!q.empty()){
ans.push_back((*--q.end()).first);
q.erase(*--q.end());
}
for(int i=0;i<ans.size();i++){
if(i==0) printf("%d",ans[i]);
else printf(" %d",ans[i]);
}puts("");
}
system("pause");
return 0;
}
p.s.最近多校遇到了很多模拟题,有的写了wa或者要调很久才能ac...还要多加练习呀!加油!

浙公网安备 33010602011771号