https://www.nowcoder.com/questionTerminal/4e1012fe691b446d88eba5db8f511692
[编程|20分] 牛牛的数列
时间限制:C/C++ 1秒,其他语言 2秒
空间限制:C/C++ 32768K,其他语言 65536K
64bit IO Format: %lld
本题可使用本地IDE编码,不做跳出限制,编码后请点击“保存并调试”按钮进行代码提交。
题目描述
牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。
输入描述:
输入包括两行,第一行包括一个整数n(1 ≤ n ≤ 10^5),即数列的长度;
第二行n个整数a_i, 表示数列中的每个数(1 ≤ a_i ≤ 10^9),以空格分割。
输出描述:
输出一个整数,表示最长的长度。
示例1输入输出示例仅供调试,后台判题数据一般不包含示例
输入
6
7 2 3 1 5 6
输出
5

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
int a[100005];
int b[100005]; //正向连续上升长度
int c[100005]; //反向连续下降长度
int main()
{  int n,i,j,k;  while(~scanf("%d",&n))  {  memset(b,0,sizeof b);  memset(c,0,sizeof c);  for(i=1;i<=n;i++)  scanf("%d",&a[i]);  b[1]=1;  for(i=1;i<n;i++)  if(a[i]<a[i+1])  b[i+1]=b[i]+1;  else  b[i+1]=1;  c[n]=1;  // puts("hhh");  for(i=n;i>1;i--)  if(a[i]>a[i-1])  c[i-1]=c[i]+1;  else  c[i-1]=1;  // for(i=1;i<=n;i++)  // printf("%d,",b[i]);  // puts("");  // for(i=1;i<=n;i++)  // printf("%d,",c[i]);  // puts("");  int ans=0;  for(i=1;i<n;i++)  {  if(a[i]>=a[i+1]) //a[i]和a[i+1]处出现跳跃  {  if(a[i+1]-2>=a[i-1]) //若修改a[i]能消除跳跃  ans=max(ans,b[i-1]+c[i+1]+1);  if(a[i]+2<=a[i+2]) //若修改a[i+1]能消除跳跃  ans=max(ans,b[i]+c[i+2]+1);  ans=max(ans,max(b[i],c[i+1])+1); //此处是  }  }  for(i=1;i<=n;i++) //未出现跳跃,取所有连续上升最大值  ans=max(ans,max(b[i],c[i]));  printf("%d\n",ans);  }  return 0;
}
数据测试
12
7 2 3 4 5 6 7 4 9 10 11 12
1 1 2 3 4 5 1 2 3 4 5 6
1 5 4 3 2 1 6 5 4 3 2 1
11

3
1 2 3
3

1
3
1

12
7 2 3 4 5 9 9 8 9 10 11 12
1 1 2 3 4 5 1 1 2 3 4 5
1 5 4 3 2 1 1 5 4 3 2 1
6