【HDU 5532 Almost Sorted Array】水题,模拟
2015-11-03 23:58
387 查看
给出一个序列(长度>=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]是否升序。
11.23更新代码如下,更加简化,速度更快
先前版本代码如下:
对任一序列,先假设其可改造为单调不降序列,若成立则输出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]是否升序。
11.23更新代码如下,更加简化,速度更快
#include <cstdio> using namespace std; const int MAX_N=100005; const int MIN_A=1; const int MAX_A=100000; int T; int n; int a[MAX_N]; int flag; int fix_cnt; int main() { freopen("5532.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } //升序 flag=1;//假设去掉最多一个元素后整体降序 fix_cnt=0; a[0]=MIN_A; a[n+1]=MAX_A; for(int i=1;i<=n-1;i++) { if(a[i]<=a[i+1]) continue; fix_cnt++; if(fix_cnt<=1&&(a[i-1]<=a[i+1]||a[i]<=a[i+2])) continue; flag=0; break; } if(flag) { printf("YES\n"); continue; } //降序 flag=1;//假设去掉最多一个元素后整体降序 fix_cnt=0; a[0]=MAX_A; a[n+1]=MIN_A; for(int i=1;i<=n-1;i++) { if(a[i]>=a[i+1]) continue; fix_cnt++; if(fix_cnt<=1&&(a[i-1]>=a[i+1]||a[i]>=a[i+2])) continue; flag=0; break; } if(flag) { printf("YES\n"); continue; } printf("NO\n"); } return 0; }
先前版本代码如下:
#include <cstdio> using namespace std; const int MAX_N=100005; const int MIN_A=1; const int MAX_A=100000; int T; int n; int in[MAX_N],de[MAX_N]; int flag; int fix_cnt; int main() { freopen("5532.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&in[i]); de[i]=in[i]; } //升序的情况 in[0]=MIN_A; in[n+1]=MAX_A; flag=1;//假设去掉最多一个元素后整体升序 fix_cnt=0; for(int i=1;i<=n-1;i++) { if(in[i]<=in[i+1]) continue; fix_cnt++;//左归的情况 if(fix_cnt<=1&&in[i-1]<=in[i+1]) continue; flag=0; break; } if(flag) { printf("YES\n"); continue; } flag=1; fix_cnt=0; for(int i=1;i<=n-1;i++) { if(in[i]<=in[i+1]) continue; fix_cnt++;//右归的情况 if(fix_cnt<=1&&in[i]<=in[i+2]) continue; flag=0; break; } if(flag) { printf("YES\n"); continue; } //降序的情况 de[0]=MAX_A; de[n+1]=MIN_A; flag=1;//假设去掉最多一个元素后整体降序 fix_cnt=0; for(int i=1;i<=n-1;i++) { if(de[i]>=de[i+1]) continue; fix_cnt++;//左归的情况 if(fix_cnt<=1&&de[i-1]>=de[i+1]) continue; flag=0; break; } if(flag) { printf("YES\n"); continue; } flag=1; fix_cnt=0; for(int i=1;i<=n-1;i++) { if(de[i]>=de[i+1]) continue; fix_cnt++;//右归的情况 if(fix_cnt<=1&&de[i]>=de[i+2]) continue; flag=0; break; } if(flag) { printf("YES\n"); continue; } printf("NO\n"); } return 0; }
相关文章推荐
- iOS NSNotificationCenter的简单使用
- iOS UI设计: 在Autolayout自适应的情况下tableviewcell高度自适应
- android:java.lang.NoClassDefFoundError: com.lidroid.xutils.HttpUtils 异常的解决
- 关于WordPress后台设置中的WordPress地址和站点地址的解读
- DisableExplicitGC和Direct ByteBuffer
- 高质量程序设计指南C++/c语言 第四章
- java架构师之路:JAVA程序员必看的15本书的电子版下载地址
- HIHO 16 B
- 如何有效控制需求变更
- Makefile 使用总结
- 控件悬停
- EditPlus4.0汉化+破解注册
- Genymotion启动失败解决方法
- [转]VC++中CTime类Format参数详解
- ListSet_无序表搜索
- JAVA的反射机制
- Android学习记录之Volley框架JSONObjectRequest
- 算法题:字符串的全排列
- leetcode-Number of Islands
- Elasticsearch - 搜索引擎Lucene