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
题意:给你一组数,能否删除一个后使他成为升序或者降序
思路:
正反分别求一次最长上升子序列,只要长度有一次≥n-1即可
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <queue> #include <vector> #include <algorithm> #include <functional> typedef long long ll; using namespace std; const int maxn = 1e5 + 5; int b[maxn]; int n; int Search(int num,int low,int high) { int mid; while(low <= high) { mid = (low+high)/2; if(num >= b[mid]) low= mid+1; else high = mid-1; } return low; } int fin(int *a) { int len,pos; b[1] = a[1]; len = 1; for(int i = 2;i <= n;i++) { if(a[i] >= b[len]) { len = len+1; b[len] = a[i]; } else { pos = Search(a[i],1,len); b[pos ] = a[i]; } } if(len >= n-1) return true; else return false; } int t[maxn],tt[maxn]; int main() { int cas; scanf("%d",&cas); while(cas--) { scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%d",t+i); for(int i = 1;i <= n;i++) tt[n+1-i] = t[i]; bool flag = fin(t); flag |= fin(tt); if(flag) printf("YES "); else printf("NO "); } }