zoukankan      html  css  js  c++  java
  • hdu 5532 Almost Sorted Array(模拟)

    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?
    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.
    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
     

    给出一个序列(长度>=2),问去掉一个元素后是否能成为单调不降序列或单调不增序列。

    对任一序列,先假设其可改造为单调不降序列,若成立则输出YES,不成立再假设其可改造为单调不增序列,若成立则输出YES,不成立则输出NO。

    由于持平不影响整体单调性,为了直观,我在以下把“不降”称为“递增/升序”,把“不增”称为“递减/降序”。

    递增和递减是对称的,这里先考虑递增,递减改个符号和最值就好。

    我们把为维护单调性而去掉的那个点称为“坏点”。由题目的要求,“可改造”可等价于“只存在一个坏点”。

    对于“坏点”的判断,我们可以先找出是否只存在一组“逆序”。

    对于“almosted sorted”递增序列,只存在一组逆序无非以下四种情况(这里先不考虑逆序在边界)。

    现在考虑逆序在边界的情况。由于a[]数组元素下标是1~n,而此题1<=ai<=100000,那么对于递增序列,可把a[0]设为1、把a[n+1]设为100000作为首尾哨兵节点,一定不会破坏整体单调性;递减序列做对称的处理。这样边界也可以像中间一样处理。

    由于三种情况满足一种即可,而第二种可以看作第三种和第四种的交集,故只需按照第三种和第四种的情况对a[]数组各进行一次遍历,满足一种即可输出YES。

    对于坏点的处理,我们采用“当它不存在”的策略,所以首次遇到坏点,忽略它,再次遇到坏点,则此种情况不成立。

    至于如何由“逆序”推出“坏点”,并实现几种情况的判断,我们遍历i:0~n,对于第一对逆序a[i]>a[i+1],我们可以:

    先采取“左归”(第三种),即把a[i]当作坏点,判断a[i-1]和a[i+1]是否升序(若不升序则相当于构成了第二对逆序,出现第二个坏点);

    若左归不成立,再采取“右归”(第四种),即把a[i+1]当坏点,同理判断a[i]和a[i+2]是否升序。

     
     1 #pragma comment(linker, "/STACK:1024000000,1024000000")
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<math.h>
     7 #include<algorithm>
     8 #include<queue>
     9 #include<set>
    10 #include<bitset>
    11 #include<map>
    12 #include<vector>
    13 #include<stdlib.h>
    14 #include <stack>
    15 using namespace std;
    16 #define PI acos(-1.0)
    17 #define max(a,b) (a) > (b) ? (a) : (b)
    18 #define min(a,b) (a) < (b) ? (a) : (b)
    19 #define ll long long
    20 #define eps 1e-10
    21 #define MOD 1000000007
    22 #define N 100006
    23 #define inf 1000000
    24 int n;
    25 int a[N];
    26 int b[N];
    27 int main()
    28 {
    29    int t;
    30    scanf("%d",&t);
    31    while(t--){
    32       scanf("%d",&n);
    33       for(int i=1;i<=n;i++){
    34          scanf("%d",&a[i]);
    35          b[i]=a[i];
    36       }
    37       int flag=1;
    38       b[0]=1;
    39       b[n+1]=inf;
    40       int num1=0;
    41       for(int i=1;i<n;i++){//
    42          if(b[i]<=b[i+1]) continue;
    43          num1++;
    44          if(b[i-1]<=b[i+1] && num1<=1) continue;
    45          flag=0;
    46          break;
    47       }
    48       if(flag){
    49          printf("YES
    ");
    50          continue;
    51       }
    52       num1=0;
    53       flag=1;
    54       for(int i=1;i<n;i++){//
    55          if(b[i]<=b[i+1]) continue;
    56          num1++;
    57          if(b[i]<=b[i+2] && num1<=1) continue;
    58          flag=0;
    59          break;
    60       }
    61       if(flag){
    62          printf("YES
    ");
    63          continue;
    64       }
    65 
    66       a[0]=inf;
    67       a[n+1]=1;
    68       int num2=0;
    69       flag=1;
    70       for(int i=1;i<n;i++){
    71          if(a[i]>=a[i+1]) continue;
    72          num2++;
    73          if(a[i-1]>=a[i+1] && num2<=1) continue;
    74          flag=0;
    75          break;
    76       }
    77       if(flag){
    78          printf("YES
    ");
    79          continue;
    80       }
    81 
    82       num2=0;
    83       flag=1;
    84       for(int i=1;i<n;i++){
    85          if(a[i]>=a[i+1])continue;
    86          num2++;
    87          if(a[i]>=a[i+2] && num2<=1) continue;
    88          flag=0;
    89          break;
    90       }
    91       if(flag){
    92          printf("YES
    ");
    93          continue;
    94       }
    95       printf("NO
    ");
    96    }
    97     return 0;
    98 }
    View Code
     
  • 相关阅读:
    linux如何编译安装新内核支持NTFS文件系统?(以redhat7.2x64为例)
    RAID磁盘阵列的搭建(以raid0、raid1、raid5、raid10为例)
    linux专题一之文件归档和压缩(tar、file、zip)
    linux专题一之文件管理(目录结构、创建、查看、删除、移动)
    CENTOS6.6上搭建单实例ORACLE12C
    oracle12c各个版本对其需要的依赖包及系统参数的修改
    mysql cp复制和mysqldump备份测试
    mysql之mysql_config_editor
    CENTOS6.6下redis3.2集群搭建
    CENTOS6.6 下mysql MHA架构搭建
  • 原文地址:https://www.cnblogs.com/UniqueColor/p/4977781.html
Copyright © 2011-2022 走看看