原题复现:
思路的火花:
本题是一道比较恶心的模拟题,运用到了栈的知识以及抗击打内心,详细解释有请代码
代码请看哎:
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
const int MAX=100005;
int a[MAX];
stack<int>st;//盒子
int main()
{
int n,m,k;
cin>>n>>m>>k;//n是推送器上产品的个数,m为盒子最大容量给,k为一根松枝干上能插的松针片的最大数量
for(int i=1; i<=n; i++)cin>>a[i];//用a数组来存推送器上的松针片
int i=1;//确保开始是从传送带上第一件物品
while(1)
{
int top=0;
if(i==n+1&&st.size()==0)break;//如果传送带上没有物品了,盒子里也没有物品了,代表无法再构造一颗松枝干
vector<int>u;//即将构造的松枝干
if(!st.empty())//由于题目要求先考虑盒子再考虑传送带
{
u.push_back(st.top());//开始时树上没有松枝片,就取盒顶的松针片作为最底部的
st.pop();
top++;
}
else u.push_back(a[i++]),top++;//如果盒子里没有松枝片了,再考虑传送带
while(1)//为后续建树
{
if(u.size()==k)break;//如果当前树上的松叶片数量满足要求,就结束手头这棵树的构造工作
if(!st.empty())//由于题目要求先考虑盒子再考虑传送带
{
if(st.top()<=u[top-1])//如果盒顶的松枝片<=手头这棵树才插好的松枝片
{
u.push_back(st.top());
st.pop();
top++;
}
else if(i<=n)//此处再去考虑传送带
{
if(a[i]<=u[top-1])u.push_back(a[i++]),top++;//目前传送带上的松枝片<=手头这棵树才插好的松枝片
else if(st.size()<m)st.push(a[i++]);//过大了就要依照题目放进盒子里,同时也要确保盒子容量
else break;//都做不到就只能结束手头这棵树的构造工作了
}
else break;//都做不到就只能结束手头这棵树的构造工作了
}
else//盒子里再没有松枝片了
{
if(i<=n)//此处再去考虑传送带
{
if(a[i]<=u[top-1])u.push_back(a[i++]),top++;//目前传送带上的松枝片<=手头这棵树才插好的松枝片
else if(st.size()<m)st.push(a[i++]);//过大了就要依照题目放进盒子里,同时也要确保盒子容量
else break;//都做不到就只能结束手头这棵树的构造工作了
}
else break;//都做不到就只能结束手头这棵树的构造工作了
}
}
cout<<u[0];
for(int i=1;i<top;i++)cout<<" "<<u[i];
cout<<endl;
}
}
//佛系过关