HDU5532-Almost Sorted Array

来源:互联网 发布:怎么运营好淘宝店铺 编辑:程序博客网 时间:2024/04/28 12:15

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=5532

题意

给一个序列,可以去掉其中一个元素,判断序列能否在去掉某个元素后成为一个有序序列

思路

因为序列可以不严格单调增/减,先单独考虑单调增的情况,减相同处理
设f(i)为以i结尾的不严格单调递增的序列长度,g(i)为以i开头的不严格单调递减的序列长度,比如如下序列a[]:
3,4,2,5,6
f[1] = 1, f[2] = 2, f[3] = 1, f[4] = 2, f[5] = 3;
g[1] = 2, g[2] = 1, g[3] = 3, g[4] = 2, g[5] = 1;
假如我们有了f[]和g[]了,则只需要枚举要去掉的元素i,使得:f[i - 1] + g[i + 1] == n - 1 && a[i + 1] >= a[i - 1]即可,时间复杂度为O(n)
则只需要得到f[]和g[]了,不难发现只需要数组分别往后和往前滚一遍就可以递推得到f[]和g[]
单调减的时候相同处理
以及有些细节需要处理一下

代码

代码比较臃肿= =

#include <iostream>#include <cstring>#include <stack>#include <vector>#include <set>#include <map>#include <cmath>#include <queue>#include <sstream>#include <iomanip>#include <fstream>#include <cstdio>#include <cstdlib>#include <climits>#include <deque>#include <bitset>#include <algorithm>using namespace std;#define PI acos(-1.0)#define LL long long#define PII pair<int, int>#define PLL pair<LL, LL>#define mp make_pair#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "wb", stdout)#define scan(x) scanf("%d", &x)#define scan2(x, y) scanf("%d%d", &x, &y)#define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z)#define sqr(x) (x) * (x)#define pr(x) cout << #x << " = " << x << endl#define lc o << 1#define rc o << 1 | 1#define pl() cout << endlconst int maxn = 100000 + 5;const int INF = 100000 + 5;int a[maxn], f[maxn], g[maxn];int n;int main() {    int T;    scan(T);    while (T--) {        scan(n);        memset(f, 0, sizeof(f));        memset(g, 0, sizeof(g));        a[0] = 0;        a[n + 1] = INF;        for (int i = 1; i <= n; i++) {            scan(a[i]);            if (a[i] >= a[i - 1]) f[i] = f[i - 1] + 1;            else f[i] = 1;        }        for (int i = n; i >= 1; i--) {            if (a[i] <= a[i + 1]) g[i] = g[i + 1] + 1;            else g[i] = 1;        }        if (n == 2) {            puts("YES");            continue;        }        if (g[1] == n || f[n] == n) {            puts("YES");            continue;        }        bool flag = false;        for (int i = 1; i <= n; i++) {            if (g[i + 1] + f[i - 1] == n - 1 && a[i + 1] >= a[i - 1]) {                flag = true;                break;            }        }        if (flag) {            puts("YES");            continue;        }        a[0] = INF, a[n + 1] = 0;        for (int i = 1; i <= n; i++) {            if (a[i] <= a[i - 1]) f[i] = f[i - 1] + 1;            else f[i] = 1;        }        for (int i = n; i >= 1; i--) {            if (a[i] >= a[i + 1]) g[i] = g[i + 1] + 1;            else g[i] = 1;        }        if (g[1] == n || f[n] == n) {            puts("YES");            continue;        }        for (int i = 1; i <= n; i++) {            if (g[i + 1] + f[i - 1] == n - 1 && a[i + 1] <= a[i - 1]) {                flag = true;                break;            }        }        if (flag) puts("YES");        else puts("NO");    }    return 0;}
0 0