合并数字
蒜頭君得到了?nn?個數,他想對這些數進行下面這樣的操作,選出最左邊的相鄰的差的絕對值為?11?的兩個數,只保留較小的數,刪去較大的數,直到沒有兩個相鄰的差的絕對值為?11?的數,問最多可以進行多少次這樣的操作?
輸入格式
輸入第一行為一個整數?n(1 \leq n \leq 10^5)n(1≤n≤105),表示數字的總數
第二行為?nn?個整數?x_1,x_2,...,x_n(0 \leq x_i \leq 10^9)x1?,x2?,...,xn?(0≤xi?≤109),表示這些數。
輸出格式
輸出一行,為一個整數,表示蒜頭君最多可以進行多少次這樣的操作。
樣例輸入
4 1 2 0 1樣例輸出
3
自己寫的超時了,看了實驗室大神用的數組鏈表的思想,感覺,,太強了。
#include <bits/stdc++.h> using namespace std; int main() {int n;int a[100005],pre[100005],next[100005];cin>>n;for(int i=1;i<=n;++i)scanf("%d",&a[i]);for(int i=1;i<=n+1;++i){pre[i]=i-1;next[i]=i+1;}a[0]=a[n+1]=-2;int ans=0;for(int i=1;i<=n;){if(i==0)i=next[i];if(a[i]-a[pre[i]]==1){next[pre[i]]=next[i];pre[next[i]]=pre[i];i=pre[i];ans++;continue;}else if(a[i]-a[pre[i]]==-1){next[pre[pre[i]]]=i;pre[i]=pre[pre[i]];i=pre[i];ans++;continue;}i=next[i];}cout<<ans<<endl;return 0; }看到學長的一個用棧來處理這道題目的方法,,,,orz~點擊打開鏈接
#include <iostream> #include <stack> using namespace std; int n,x; int ans=0; //最大操作次數 stack<int> st; int main() {int i;cin>>n;for(i=0;i<n;i++){cin>>x;//將x與當前棧頂元素st.top()比較,若棧不空且st.top()比x大1,則合并一次(此時即當前棧頂元素出棧)//然后x與次棧頂比較,以此類推,直到不滿足棧不空且st.top()比x大1 while(!st.empty() && st.top()-x==1){st.pop();ans++;}//若棧不空且x比st.top()大1,則合并一次//(此時即x"出棧",也就是忽略此x繼續看下一個輸入的x 但棧不發生任何變化) if(!st.empty() && x-st.top()==1)ans++;//其他情況(x為第一個元素或不滿足上述兩種情況):將x入棧elsest.push(x);}cout<<ans<<endl;return 0; }總結