2015ACM/ICPC亚洲区长春站 F hdu 5533 Almost Sorted Array
Almost Sorted Array
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 447 Accepted Submission(s): 201
Problem Description
We are all familiar with sorting algorithms: quick sort, merge sort, heap sort, insertion sort, selection sort, bubble sort, etc. But sometimes it is an overkill to use these algorithms for an almost sorted array.
We say an array is sorted if its elements are in non-decreasing order or non-increasing order. We say an array is almost sorted if we can remove exactly one element from it, and the remaining array is sorted. Now you are given an array a1,a2,…,an, is it almost sorted?
We say an array is sorted if its elements are in non-decreasing order or non-increasing order. We say an array is almost sorted if we can remove exactly one element from it, and the remaining array is sorted. Now you are given an array a1,a2,…,an, is it almost sorted?
Input
The first line contains an integer T indicating the total number of test cases. Each test case starts with an integer n in one line, then one line with n integers a1,a2,…,an.
1≤T≤2000
2≤n≤105
1≤ai≤105
There are at most 20 test cases with n>1000.
1≤T≤2000
2≤n≤105
1≤ai≤105
There are at most 20 test cases with n>1000.
Output
For each test case, please output "`YES`" if it is almost sorted. Otherwise, output "`NO`" (both without quotes).
Sample Input
3
3
2 1 7
3
3 2 1
5
3 1 4 1 5
Sample Output
YES
YES
NO
Source
题意:如果一组数去掉一个是不降或不升的,那么这组数是满足性质的,问给出的这组数是否满足性质。
分析:显然如果这组数本来就是不降或不升的,显然满足性质。
然后发现。。。不就是求max(最长不降子序列的长度,最长不升子序列的长度)是否大于等于n-1吗。。。
求最长不升子序列可以将数组反过来,再做一次最长不降子序列
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <ctime> 6 #include <iostream> 7 #include <map> 8 #include <set> 9 #include <algorithm> 10 #include <vector> 11 #include <deque> 12 #include <queue> 13 #include <stack> 14 using namespace std; 15 typedef long long LL; 16 typedef double DB; 17 #define MIT (2147483647) 18 #define MLL (1000000000000000001LL) 19 #define INF (1000000001) 20 #define For(i, s, t) for(int i = (s); i <= (t); i ++) 21 #define Ford(i, s, t) for(int i = (s); i >= (t); i --) 22 #define Rep(i, n) for(int i = (0); i < (n); i ++) 23 #define Repn(i, n) for(int i = (n)-1; i >= (0); i --) 24 #define mk make_pair 25 #define ft first 26 #define sd second 27 #define puf push_front 28 #define pub push_back 29 #define pof pop_front 30 #define pob pop_back 31 #define sz(x) ((int) (x).size()) 32 inline void SetIO(string Name) 33 { 34 string Input = Name + ".in"; 35 string Output = Name + ".out"; 36 freopen(Input.c_str(), "r", stdin); 37 freopen(Output.c_str(), "w", stdout); 38 } 39 40 inline int Getint() 41 { 42 char ch = ' '; 43 int Ret = 0; 44 bool Flag = 0; 45 while(!(ch >= '0' && ch <= '9')) 46 { 47 if(ch == '-') Flag ^= 1; 48 ch = getchar(); 49 } 50 while(ch >= '0' && ch <= '9') 51 { 52 Ret = Ret * 10 + ch - '0'; 53 ch = getchar(); 54 } 55 return Ret; 56 } 57 58 const int N = 100010; 59 int n, Arr[N]; 60 int Cnt[N], Len, Ans; 61 62 inline void Solve(); 63 64 inline void Input() 65 { 66 int TestNumber = Getint(); 67 while(TestNumber--) 68 { 69 n = Getint(); 70 For(i, 1, n) Arr[i] = Getint(); 71 Solve(); 72 } 73 } 74 75 inline int Find(int x) 76 { 77 int Left = 1, Right = Len, Mid, Ret = Len + 1; 78 Cnt[Len + 1] = INF; 79 while(Left <= Right) 80 { 81 Mid = (Left + Right) >> 1; 82 if(Cnt[Mid] > x) Ret = Mid, Right = Mid - 1; 83 else Left = Mid + 1; 84 } 85 return Ret; 86 } 87 88 inline void Work() 89 { 90 Cnt[1] = Arr[1], Len = 1; 91 For(i, 2, n) 92 { 93 int x = Find(Arr[i]); 94 Cnt[x] = Arr[i]; 95 Len = max(Len, x); 96 } 97 } 98 99 inline void Solve() 100 { 101 Ans = 0; 102 Work(); 103 Ans = max(Ans, Len); 104 For(i, 1, n / 2) swap(Arr[i], Arr[n - i + 1]); 105 Work(); 106 Ans = max(Ans, Len); 107 108 if(Ans >= n-1) puts("YES"); 109 else puts("NO"); 110 } 111 112 int main() 113 { 114 Input(); 115 //Solve(); 116 return 0; 117 }