乐乐做完数学作业,突发奇想定义了一种新的数:乐乐数。乐乐把n个数排成一行,一个数的“乐乐数”是指:在这个数的左边且比它小的数中最靠近它(即最靠右)的那个数。依次给出这n个数,请求出所有这n个数相对应的“乐乐数”。
第一行是一个正整数n,表示一共有多少个数。 第二行有n个用空格隔开的正整数,它们从左至右给出了数列中的n个数。这些数保证小于2^31。
输出一行用空格隔开的n个数。 这些数对应于输入数据中的数的“乐乐数”。如果输入中某个数没有“乐乐数”(即它左边的数都不比它小),请输出0。
7 3 1 2 7 6 7 4
5 5 6 3 10 9
0 0 1 2 2 6 2
0 5 0 3 3
对于80%的数据,n≦10000; 对于100%的数据,n≦200000。
此题我们需要先看看这个数据范围,可以看到这个数据范围非常大,所以不能采用两重循环暴力求解法,否则会超时,那要怎么办呢?这时我们就需要考虑新的算法,我们可以牺牲空间减少时间,只要再加一个数组就可以了。这个数组我们就命名为B数组,这个数组主要是拿来储存前一个比他小的数。接着就是1~N的循环了,我们为了减少时间,这里不能直接两重循环,而是可以利用判断+while来解决。进入第一层循环,假如A[i-1]>A[i]的话,我们就需要更新一下内容了,B[i]需要赋值为A[i-1],而我们的NEXT[i]=i-1。但如果不成立的话变量NXT赋值为NEXT[i-1],然后就是while循环,循环的条件就是NXT不为零并且A[NXT]>=A[i],循环内容就是NXT=NEXT[NXT],这个循环主要的功能就是不停的搜索数字了。
以上为主要的内容解释,接下来上代码👇👇👇
#include<bits/stdc++.h> using namespace std; int t[200001],a[200001],ans[200001]; int main() { int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ if(!(a[i-1]<a[i])){ int temp=t[i-1]; while(temp!=0&&a[temp]>=a[i]){ temp=t[temp]; } ans[i]=a[temp]; t[i]=temp; } else{ ans[i]=a[i-1]; t[i]=i-1; } } for(int i=1;i<=n;i++){ cout<<ans[i]<<" "; } return 0; }结合代码和思路应该是能够看懂并理解的,如果还有不懂请在下方留言,我会尽快解答哦(づ ̄3 ̄)づ╭❤~更多题目解析请看我的个人主页