【编程|20分】牛牛的数列
时间限制:C/C++1秒,其他语言2秒
空间限制:C/C++32768K,其他语言65536K
64bit IO Format:%lld
题目描述:
牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。
输入描述:
输入包括两行,第一行包括一个整数n(1 ≤ n ≤ 10^5),即数列的长度;
第二行n个整数a_i, 表示数列中的每个数(1 ≤ a_i ≤ 10^9),以空格分割。
输出描述:
输出一个整数,表示最长的长度。
示例1(输入输出示例仅供调试,后台判题数据一般不包含示例)
输入:
6
7 2 3 1 5 6
输出:
5
AC代码:
法一:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
while (cin >> n)
{
vector<int> v(n, 0);
for (int i = 0; i < n; ++i)
cin >> v[i];
if (n == 0 || n == 1)
{
cout << n << endl;
continue;
}
vector<int> dp1(n, 0);
vector<int> dp2(n, 0);
dp1[n - 1] = 1;
for (int i = n - 2; i >= 0; --i)
{
if (v[i] < v[i + 1])
dp1[i] = dp1[i + 1] + 1;
else
dp1[i] = 1;
}
dp2[0] = 1;
for (int i = 1; i < n - 1; ++i)
{
if (v[i] > v[i - 1])
dp2[i] = dp2[i - 1] + 1;
else
dp2[i] = 1;
}
int ret = 1;
int m = 1;
for (int i = 0; i < n - 1; ++i)
{
if (i == 0)
m = dp1[i + 1] + 1;
else if (i == n - 1)
m = dp2[i - 1] + 1;
else if (v[i - 1] + 1 < v[i + 1])
m = dp1[i + 1] + dp2[i - 1] + 1;
else
m = max(dp1[i + 1], dp2[i - 1]) + 1;
if (m > ret)
ret = m;
}
cout << ret << endl;
}
return 0;
}
法二:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
int a[N];
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d", &a[i]);
vector<int> left(n), right(n);
left[0] = right[n - 1] = 1;
for (int i = 1; i < n; ++i)
left[i] = a[i - 1] < a[i] ? left[i - 1] + 1 : 1;
for (int i = n - 2; i >= 0; --i)
right[i] = a[i] < a[i + 1] ? right[i + 1] + 1 : 1;
long long ans = 1;
for (int i = 1; i + 1 < n; ++i)
{
if (a[i - 1] < a[i + 1])
{
ans = max(ans, (long long)left[i - 1] + right[i - 1] + 1);
}
}
printf("%d", ans);
return 0;
}
两个代码都可以AC过,法一能过的了VS2019,但是VS2019不支持法二的
#include<bits/stdc++.h>
这个头文件,所以法二过不了VS2019,但是法一、法二都是对的,且在DEV-C++5.11都能运行。
第八题法一,在DEV-C++5.11和VS2019中,输入数据,再按回车无结果。正确方法是输入数据,按回车,再按CTRL+Z,再按回车,最后才会产生结果。