解题思路:模拟+合并,队列实现
2026-08-11 21:09:07
发布于:浙江
9阅读
0回复
0点赞
这道题思路挺难想的,花了一个小时才想到,想到思路又花了13分钟才写出来

这道题如果直接模拟只能得70分,原因是每一次模拟都要吧整个数组都遍历一遍,所以我们可以定义一个结构体asdf把每个块的起始点(id) , 长度(size) 和水果的种类(x)都存储起来。但如果用数组,在模拟的过程中把长度为零的块去除会很麻烦,所以可以用队列,这样只要pop就好了。但去除后还要把其他的合并,比如[1 1] [0 0] [1 1 1] [0] [1 1] [0 0] -> [1] [0] [1 1] [] [1] [0] -> [1] [0] [1 1 1] [0]不然每一个没合并的你都要枚举,还是会超时。但会有一个问题,如果有多个连续的块要合并只靠这个数组就不够了,所以要再定义一个队列hb(合并)把每一次模拟后的结果存进去,然后进行合并,再放入原来的队列。
q:[1 1] [0 0] [1 1 1] [0] [1 1] [0 0] //逐个快枚举,处理后存进hb里,并把处理过的pop
| | | | | |
hb: [1] [0] [1 1] [] [1] [0] -> [1] [0] [1 1 1] [0]//合并
|
q:[1] [0] [1 1 1] [0]//存入q中,把hb清空
那么要如何枚举呢?
把每一个在q队列里的块都枚举一遍,输出起始点(id)。
在合并时会出现一个问题,合并之后的块的每一个水果的下标不一定是连续的,普通的加1不能正确的输出下标,所以可以定义一个bool类型的数组vis来记录哪一个下标被输出过了,然后for循环找下一个没被输出过的,将新的起始点=下一个没被输出过的下标。然后存入hb中
while(!q.empty()){
asdf qwer = q.front();
q.pop();
qwer.size--;
cout << qwer.id << " ";
vis[qwer.id] = false;
for(int j = qwer.id; j <= n; j++){
if(vis[j]){
qwer.id = j;
break;
}
}
if(qwer.size > 0){
hb.push(qwer);
}
}
那么要如何合并呢?
定义一个asdf类型的变量qwer=hb.front()
然后while循把每一个水果的种类与qwer一样的与qwer合并:把qwer.size 加上这个要合并的长度。
while(!hb.empty()){
asdf qwer = hb.front();
if(qwer.size == 0){
hb.pop();
continue;
}
hb.pop();
while(!hb.empty() && hb.front().x == qwer.x){
qwer.size += hb.front().size;
hb.pop();
}
q.push(qwer);
}
那么这道题的思路就讲完了,满分代码如下
#include<bits/stdc++.h>
using namespace std;
int n;
struct asdf{
int x , id , size;
}a[200005];
queue<asdf> q , hb;
bool vis[200005];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
while(!q.empty()){
q.pop();
}
while(!hb.empty()){
hb.pop();
}
for(int i = 1; i <= n; i++){
cin >> a[i].x;
vis[i] = true;
}
int x = -1;
for(int i = 1; i <= n; i++){
if(a[i].x != x){
asdf p;
p.x = a[i].x;
p.id = i;
int num = 0;
while(i <= n && a[i].x ==a[p.id].x){
num++;
i++;
}
p.size = num;
q.push(p);
i--;
}
}
while(!q.empty()){
while(!q.empty()){
asdf qwer = q.front();
q.pop();
qwer.size--;
cout << qwer.id << " ";
vis[qwer.id] = false;
for(int j = qwer.id; j <= n; j++){
if(vis[j]){
qwer.id = j;
break;
}
}
if(qwer.size > 0){
hb.push(qwer);
}
}
cout << "\n";
while(!hb.empty()){
asdf qwer = hb.front();
if(qwer.size == 0){
hb.pop();
continue;
}
hb.pop();
while(!hb.empty() && hb.front().x == qwer.x){
qwer.size += hb.front().size;
hb.pop();
}
q.push(qwer);
}
}
return 0;
}
这里空空如也




有帮助,赞一个