17-比赛1 A - Weak in the Middle (栈)
題目描述
給定長度為 N 的序列 A。每天,序列 A 中所有比兩側元素都小的元素都會消失。
對于原序列中所有元素,請求出它會在第幾天之后消失(天數從 1 開始計算),或者指出它不
會消失。
數據范圍
1 ≤ T ≤ 1, 000
1 ≤ N ≤ 1e5
1 ≤ Ai ≤ 1e9
輸入格式
輸入的第一行包含一個整數 T,代表測試數據的組數。接下來是 T 組數據。
每組數據的第一行包含一個整數 N。第二行包含 N 個整數 A1, A2, . . . , AN。
輸出格式
對于每組數據,輸出一行,包含 N 個整數。第 i 個整數代表第 i 個元素在第幾天消失;如果
它不會消失,則應當為 0。
樣例輸入
1
6
3 2 5 4 1 7
樣例輸出
0 1 0 2 1 0
========================================================================================================================================================
關鍵詞 : 棧?
當時比賽未解決的題目
學長的題解 :
因為需要計算出在第幾天被刪除,暴力的做法必然會導致超時;
因此可以用棧來簡化,求出最后剩下的;
設當前處理的數為 a[i],棧頂元素為 st[top]?
如果 st[top]-1>st[top]<a[i];
則 刪除棧頂元素 將 a [i] 壓入棧
被刪除的天數則考慮反證法,某一個數a[i]很大? , 多次參與 刪除,則最后 一個因為a[i] 被刪除的數的天數一定是 max(a[i]參與過的次數,該數參與過的次數) + 1 ,a[i] 參與的次數又發生變化。?
========================================================================================================================================================
代碼實現如下
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 10; 4 5 int ans[N],a[N],st[N],Max[N],top; 6 7 int main() 8 { 9 int T; scanf("%d",&T); 10 while(T--) 11 { 12 int n; 13 scanf("%d",&n); 14 for(int i = 1;i <= n ;++i) ans[i] = Max[i] = 0; top = 0; //初始化 15 for(int i = 1;i <= n ;++i) scanf("%d",a + i); 16 for(int i = 1;i <= n ;++i){ 17 while(top>=2&&a[st[top]]<a[st[top-1]]&&a[st[top]] < a[i]) 18 { 19 ans[st[top]] = max(Max[st[top-1]],Max[st[top]])+1; //當前被刪除的次數為max(前一位參與的次數,棧頂參與的次數)+1 20 Max[st[top-1]] = ans[st[top]]; //前一位參與了這次刪除,次數變化 21 --top; 22 } 23 st[++top] = i; 24 } 25 for(int i = 1;i <= n;++i) printf(i==n?"%d\n":"%d ",ans[i]); 26 } 27 28 return 0; 29 }?
轉載于:https://www.cnblogs.com/darkboy/p/9382095.html
總結
以上是生活随笔為你收集整理的17-比赛1 A - Weak in the Middle (栈)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序开发02-小程序基本介绍
- 下一篇: 043 hive数据同步到mysql