上天很有意思,貓喜歡喫魚,貓卻不能下水;
魚喜歡喫蚯蚓,魚卻不能上岸.
人生,就是一邊擁有,一邊失去,一邊選擇,一邊放棄.
人生,哪有事事如意,生活,哪有樣樣順心.
所以,不和別人較真,因爲不值得;
不和自己較真,因爲傷不起,不和往事較真,因爲回不去!–<卡農>
【題目要求】
| 時間限制:1秒 | 內存限制:32768K
【題目描述】:
牛牛定義排序子序列爲一個數組中一段連續的子序列,並且這段子序列是非遞增或者非遞減排序的。牛牛有一 個長度爲n的整數數組A,他現在有一個任務是把數組A分爲若干段排序子序列,牛牛想知道他最少可以把這個數 組分爲幾段排序子序列.
如樣例所示,牛牛可以把數組A劃分爲[1,2,3]和[2,2,1]兩個排序子序列,至少需要劃分爲2個排序子序列,所以輸出 2 輸入描述: 輸入的第一行爲一個正整數n(1 ≤ n ≤ 10^5)
第二行包括n個整數A_i(1 ≤ A_i ≤ 10^9),表示數組A的每個數字。 輸出描述: 輸出一個整數表示牛牛可以將A最少劃分爲多少段排序子序列 示例1: 輸入 6 1 2 3 2 2 1 輸出 2
【題目解析】
本題要求解的是排序子序列,排序子序列爲非遞增或者非遞減,很多同學在這個非遞增、非遞減問題上很糾 結,注意:非遞減就是a[i]<=a[i+1],遞減就是a[i]>a[i+1],非遞增就是a[i]>=a[i+1],遞增就是a[i]<a[i+1]。
【解題思路】
1.本題依次比較整個數組
2. a[i+1]>a[i] ,則進入非遞增序列判斷,直到遍歷到下一個值不大於等於爲止count++,然後進行下一位 置的判斷
3. a[i+1]<a[i],則進入非遞增序列判斷,直到遍歷到下一個值不小於等於爲止count++,然後進行下一位 置的判斷
4. a[i+1] == a[i]不進行操作,++i進行下一位置遍歷,因爲相等既可以屬於非遞增序列,也可以屬於非遞減 序列。
【本題注意點】
本題開始比較a[i+1]與a[i]進行比較,爲了避免越界,數組定義爲n+1個,同時給a[n] = 0; a[n] = 0帶來的影響
【分三種情況討論】
1.若到a[n-1] 的最後一組是非遞減序列,當i == n-1,a[i] >a[i+1],因爲前面的數都是大於0的,這個輸入 條件已經說明了(去看看題目輸入條件描述),裏面的循環結束,i++,count++,i == n,外面的循環結 束。
2.若到a[n-1] 的最後一組是非遞增序列,當i == n-1,a[i] >a[i+1],因爲前面的數都是大於0的,這個輸入 條件已經說明了(去看看題目輸入條件描述),循環再走一次,i++, i== n,裏面的循環結束,i++, count++,i == n+1,外面的循環結束。
3.第三種情況 1 2 1 2 1最後一個數是單獨的情況,後面補個0,序列變成1 2 1 2 1 0,當走完全面的序列 i==n-1時,a[i] > a[i+1],進入判斷出一個非遞增序列,count++,i++,循環結束。 4. 也就是說數組最後一個位置多增加一個0,不會影響第1、2情況的判斷,主要是幫助第3情況的正確判斷。
【程序代碼】
#include<iostream>
#include<vector>
using namespace std;
// 本題牛客測試用例不全,至少應該增加以下兩組測試用例
// 輸入:
// 4
// 1 3 2 3
// 輸出:2
// 輸入:
// 6
// 3 2 1 1 2 3
// 輸出:2
int main() {
int n;
cin >> n;
// 注意這裏多給了一個值,是處理越界的情況的比較,具體參考上面的解題思路
vector<int> a;
a.resize(n + 1);
a[n] = 0;
//讀入數組
int i = 0;
for (i = 0; i < n; ++i){
cin >> a[i];
}
i = 0;
int count = 0;
while (i < n){
// 非遞減子序列
if (a[i] < a[i + 1]){
while (i < n && a[i] <= a[i + 1]){
i++;
}
count++;
i++;
}
else if (a[i] == a[i + 1]){
i++;
}
// 非遞增子序列
else {
while (i < n && a[i] >= a[i + 1]){
i++;
}
count++;
i++;
}
}
cout << count << endl;
return 0;
}