【HDU 5532 Almost Sorted Array】水题,模拟

给出一个序列(长度>=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 #include <cstdio>
 2 using namespace std;
 3
 4 const int MAX_N=100005;
 5 const int MIN_A=1;
 6 const int MAX_A=100000;
 7 int T;
 8 int n;
 9 int in[MAX_N],de[MAX_N];
10 int flag;
11 int fix_cnt;
12
13 int main()
14 {
15     freopen("5532.txt","r",stdin);
16     scanf("%d",&T);
17     while(T--)
18     {
19         scanf("%d",&n);
20         for(int i=1;i<=n;i++)
21         {
22             scanf("%d",&in[i]);
23             de[i]=in[i];
24         }
25
26         //升序的情况
27         in[0]=MIN_A;
28         in[n+1]=MAX_A;
29         flag=1;//假设去掉最多一个元素后整体升序
30         fix_cnt=0;
31         for(int i=1;i<=n-1;i++)
32         {
33             if(in[i]<=in[i+1]) continue;
34             fix_cnt++;//左归的情况
35             if(fix_cnt<=1&&in[i-1]<=in[i+1]) continue;
36             flag=0;
37             break;
38         }
39         if(flag)
40         {
41             printf("YES\n");
42             continue;
43         }
44         flag=1;
45         fix_cnt=0;
46         for(int i=1;i<=n-1;i++)
47         {
48             if(in[i]<=in[i+1]) continue;
49             fix_cnt++;//右归的情况
50             if(fix_cnt<=1&&in[i]<=in[i+2]) continue;
51             flag=0;
52             break;
53         }
54         if(flag)
55         {
56             printf("YES\n");
57             continue;
58         }
59         //降序的情况
60         de[0]=MAX_A;
61         de[n+1]=MIN_A;
62         flag=1;//假设去掉最多一个元素后整体降序
63         fix_cnt=0;
64         for(int i=1;i<=n-1;i++)
65         {
66             if(de[i]>=de[i+1]) continue;
67             fix_cnt++;//左归的情况
68             if(fix_cnt<=1&&de[i-1]>=de[i+1]) continue;
69             flag=0;
70             break;
71         }
72         if(flag)
73         {
74             printf("YES\n");
75             continue;
76         }
77         flag=1;
78         fix_cnt=0;
79         for(int i=1;i<=n-1;i++)
80         {
81             if(de[i]>=de[i+1]) continue;
82             fix_cnt++;//右归的情况
83             if(fix_cnt<=1&&de[i]>=de[i+2]) continue;
84             flag=0;
85             break;
86         }
87         if(flag)
88         {
89             printf("YES\n");
90             continue;
91         }
92         printf("NO\n");
93     }
94     return 0;
95 }
时间: 2024-10-08 05:11:04

【HDU 5532 Almost Sorted Array】水题,模拟的相关文章

hdu 5532 Almost Sorted Array (水题)

Almost Sorted Array Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 8541    Accepted Submission(s): 1982 Problem Description We are all familiar with sorting algorithms: quick sort, merge sort

hdu 5532 Almost Sorted Array nlogn 的最长非严格单调子序列

Almost Sorted Array Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2504    Accepted Submission(s): 616 Problem Description We are all familiar with sorting algorithms: quick sort, merge sort,

HDU 5532 Almost Sorted Array

Almost Sorted Array Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 831    Accepted Submission(s): 293 Problem Description We are all familiar with sorting algorithms: quick sort, merge sort,

HDU 5532——Almost Sorted Array——————【技巧】

Almost Sorted Array Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 236    Accepted Submission(s): 113 Problem Description We are all familiar with sorting algorithms: quick sort, merge sort,

HDU 5532 Almost Sorted Array(最长不下降或不上升子序列)

题目戳这 题目:给你一个序列,问你,这个序列只减少一个元素,减少之后是否为不上升序列或者不下降序列. 思路:直接对序列求最长不下降和不上升子序列,如果这个子序列的长度为n-1或者n的话,就符合题目条件. 最长不下降子序列和最长不上升子序列:这里使用数据结构的方法求最长不上升(下降)子序列的长度.就是另外构造一个数组 f[] ,这个数组表示的意思是:f [ i ] 表示的是长度为 i 的子序列的最小(最大值),因为,同样长度的子序列,最后一个数字最小或最大的时候,更方便往后面放数字.这个时候可能会

hdu 1999 不可摸数 水题。

不可摸数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7966    Accepted Submission(s): 2024 Problem Description s(n)是正整数n的真因子之和,即小于n且整除n的因子和.例如s(12)=1+2+3+4+6=16.如果任何数m,s(m)都不等于n,则称n为不可摸数. Input 包

HDU Senior&#39;s Gun (水题)

题意:给n把枪,m个怪兽,每把枪可消灭1怪兽,并获得能量=枪的攻击力-怪兽的防御力.求如何射杀能获得最多能量?(不必杀光) 思路:用最大攻击力的枪杀防御力最小的怪兽明显可获得最大能量.如果每把枪都去射杀刚好1点能量都拿不到的怪物,那简直等于把枪全丢掉. 1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include <iostream> 3 #include <stdio.h> 4 #inc

HDU 5590 ZYB&#39;s Biology 水题

ZYB's Biology Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5590 Description ZYB(ZJ−267)在NOIP拿到600分之后开始虐生物题,他现在扔给你一道简单的生物题:给出一个DNA序列和一个RNA序列,问它们是否配对. DNA序列是仅由A,C,G,T组成的字符串,RNA序列是仅由A,C,G,U组成的字符串. DNA和RNA匹配当且仅当每

hdu 4847 Wow! Such Doge! 水题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4847 统计文本中一共有多少个“Doge” 水题 #include <cstring> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <cstdio> #includ