1. 洛谷p-1190 接水问题
题目描述
学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为 1。
现在有 n 名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺序从 1到 n 编号,i 号同学的接水量为i。接水开始时,1 到 m 号同学各占一个水龙头,并同时打开水龙头接水。当其中某名同学 j 完成其接水量要求 wj 后,下一名排队等候接水的同学 k 马上接替 j 同学的位置开始接水。这个换人的过程是瞬间完成的,且没有任何水的浪费。即 j 同学第 x 秒结束时完成接水,则 k 同学第 x+1 秒立刻开始接水。若当前接水人数 n′ 不足 m,则只有 ′n′ 个龙头供水,其它 ′m−n′ 个龙头关闭。
现在给出 n 名同学的接水量,按照上述接水规则,问所有同学都接完水需要多少秒。
输入格式
第一行两个整数 n 和 m,用一个空格隔开,分别表示接水人数和龙头个数。
第二行 n 个整数 1,2,…,w1,w2,…,wn,每两个整数之间用一个空格隔开,wi 表示 i 号同学的接水量。
输出格式
一个整数,表示接水所需的总时间。
输入输出样例
输入 #1复制
5 3 4 4 1 2 1
输出 #1复制
4
输入 #2复制
8 4 23 71 87 32 70 93 80 76
输出 #2复制
163
题目分析
- 根据题意我们得出可以用循环来模拟这个水龙头接水的过程
- 用数组来模拟水龙头,分别存放学生所需要的接水量
- 先模拟水龙头一秒的接水量
- 当一个学生接完水后让下一个正在等待接水的学生立刻来这个水龙头接水(这里可以理解为把下一个正在等待接水的学生的接水量重新赋值给了这个水龙头对应的数组)
- 根据学生个数来循环确定学生全部接满时所需的时间
代码示例
#include<bits/stdc++.h>
using namespace std;
int m,n,ans,t;
int s[10001];
int main()
{
cin>>n>>m;//n代表接水人数,m代表龙头个数
for(int i=1; i<=n; i++)
cin>>s[i];
t=m+1;//t的值是下一轮接水时下一个学生编号
while(t<=m+n)//当下一轮接水的学生编号等于m+n+1时表示所有学生都已经接满了
{ //因为t先开始是m+1,然后满足一个学生的接水量时t就加一,又因为要满足n个学生的接水量,所以t等于m+n+1时所有学生才接满水
for(int i=1; i<=m; i++)//模拟每秒钟每个水龙头接水的过程
{
s[i]--;//学生所需的接水量减一
if(s[i]==0)
{
s[i]=s[t]; //如果这学生的接水量为0的话,那么就把这个水龙头让给下一个学生
t++;//下一个接水学生的编号加一
}
}
ans++;//时间加一秒
}
cout<<ans;
return 0;
}
2.洛谷p5788-单调栈模拟
题目描述
给出项数为 n 的整数数列 1…a1…n。
定义函数 f(i) 代表数列中第 i 个元素之后第一个大于 ai 的元素的下标,即 f(i)=mini<j≤n,aj>ai{j}。若不存在,则 f(i)=0。
试求出 f(1…n)。
输入格式
第一行一个正整数 n。
第二行 n 个正整数 1…a1…n。
输出格式
一行 n 个整数表示 (1),(2),…,()f(1),f(2),…,f(n) 的值。
输入输出样例
输入 #1复制
5 1 4 2 3 5
输出 #1复制
2 5 4 5 0
题目分析
- 单调栈就是栈内的元素要有单调性,可以是单调递增也可以是单调递减
- 单调栈的实现方法:从后面往前面开始扫描,当遇到比栈顶大的元素,把栈顶弹出去,注意,弹出去的过程是一个循环的过程,因为可能弹出去之后的新的栈顶也会小于这个元素,直到栈为空或者栈顶大于这个元素时结束,该元素入栈
- 栈里面放的数据是下标且还得另开一个数组来存放答案
- 运用三目运算符来把满足要求的栈顶写入答案数组
代码示例
#include<bits/stdc++.h>
using namespace std;
int a[3000001],f[3000001],n;
stack<int>k;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);//输入数据
for(int i=n;i>=1;i--)
{
while(!k.empty()&&a[k.top()]<=a[i])k.pop();//将该元素与栈顶所代表的元素相比较,如果大于栈顶,则弹出栈顶
f[i]=k.empty()?0:k.top();//栈顶为空就是0不为空的话栈顶就是答案,存入答案数组
k.push(i);//元素下标入栈
}
for(int i=1;i<=n;i++)
printf("%d ",f[i]);//输出答案数组
}
如上面有说错的地方欢迎各位大佬指出问题。