//解题思路:
// 游标=0
//先从头取第一次递增长度,结果值也等于此次长度
// 进入循环
// 游标 +=上次长度,如果游标==数组长度,退出循环
//取游标位置递增长度
//取的长度>=结果值,则结果值=取的长度+1
//本次取的长度如果能与上次增长长度拼接且大于结果值,则结果值=拼接值
//记录当前值
//游标不到最后继续循环
//最后输出结果值
YZF 有一个序列 A,由 n 个整数组成。
我们将子段 A 称为 Ai、Ai +1、Ai+ 2、…Aj(1<=i<=j=n)表示 A 的子段。
你的任务是找到 A 的最长的子段,这样就可以从子段最多改变一个数(可改变为任一个整数),使子段严格地增加。
输出找到的最长子段的长度即可。
★数据输入
输入第一行为一个正整数 n
第二行为 n 个数,第 i 个代表 ai。,0<=ai<=1000000000
对于 30%的数据,1<=n<=666;
对于 100%的数据,1<=n<=100086;
★数据输出
输出找到的最长子段的长度即可。
Kyungsoo(3252627372) 2022-09-08 19:51:40
★实验任务
设有 n 个人偶围成一个圈,一开始都有一个编号,然后为每人偶手里都握着一个令牌,令牌上有一个数字(随机生成的),和下个倒霉人偶有关。
第一个击的是第一个人偶,下次射击的从被打倒的人偶以后的第一个人偶开始数,往后数第 ai 个(是为其令牌上写明的数字数)。注意人偶被打到则出列。
以上过程直到所有人都出列为止。
★数据输入
第 1 行一个整数 n(1<=n<=3000),代表人偶数,
第 2 行有 n 个空格隔开的整数代表按时间顺序被打倒的人偶的编号(1<=ai<=1000)。
★数据输出
被打倒的人偶的编号
-
-
- #define _CRT_SECURE_NO_WARNINGS
- #include
-
- int cntAscendingLength(int[], int , int);//统计数组第start位置到size中升序的长度
- int cntAscendingLength(int a[], int start, int size)//统计数组第start位置到size中升序的长度
- {
- int cnt = 1, i = 0;
- for (i = start; i < size - 1; i++)
- if (a[i] < a[i + 1])cnt++; else return cnt;
- }
- int main()
- {
- int a[100086];//数组
- int i = 0;//遍历数组的游标,从0游到尾,没有回头的情况
- int n;//[1,100086]
- int ans=0;//最后结果
- int current;//i所在位置之后的长度记录
- int previous;//上一组的长度
-
- scanf("%d",&n);//数组 共 n个元素
- for (i = 0; i < n; i++)//每个元素的值
- scanf("%d",a+i);
-
- current = cntAscendingLength(a,0,n);//统计开始的最大增长
- previous = current;//记录当前长度
- ans = current;//第一次的长度
- i = 0;
- while (i < n ) //游标在合理范围就循环
- {
-
- if ((i += previous) == n)break; // i加上 上次最大增长值实现向后游 扫到尾直接退出
- current = cntAscendingLength(a, i, n);//取i位置的最大增长长度值
- //分两种情况比较
-
- //1 当前长度与ans的比较
- //如果现在的长度比ans一样或还要长,则保存
- ans = ans <= current ? current+1 : ans;
-
- //2 如果上次最大长度与本次最大长度可以拼接,再与ans比较
- //如果i位置值改了能连接前后,则比较
- // 1 6 6 8 第2个6 要大于前面值, +1后要小于后面的值
- if (a[i] <= a[i - 1] && a[i]+1 < a[i + 1])
- ans = ans < previous + current ? previous + current : ans;
-
- previous = current;//记录当前长度
- }
- printf("%d\n",ans);
- return 0;
- }
-
-
-
-
- //#define M 3000
- //int main()
- //{
- // int i,n, a[M] = {0}, vis[M] = { 0 };
- // // a[]令牌信息,vis[]已经被打倒的人偶就置1,没打倒就置0
- // scanf("%d", &n); //输入人数
- // for (i = 0; i < n; i++)
- // scanf("%d",a+i);//每个人手里的令牌数
- //
- //
- // int cur = 0, nextag; //cur当前 //nextag下一个
- // for (i = 0; i < n; i++)
- // {
- // printf("%d ", cur + 1);//输出要倒下的当前编号
- // vis[cur] = 1;//标记倒下
- // nextag = a[cur];//用nextag记下倒的人手里的令牌
- //
- // if (i < n - 1 ) // i==n-1时就只剩一个未打倒人偶了,不需要再找下一个
- // {
- // while (nextag)//当nextag为0 循环结束,代表找到要倒下的人的位置了
- // {
- // cur = ++cur%n; //移动 范围[0到n-1]
- // if (vis[cur] == 0) nextag--;//如果没位置没打倒,nextag--
- // }
- // }
- // }
- //
- // return 0;
- //}
-
- /*
- ★实验任务
- 设有 n 个人偶围成一个圈,一开始都有一个编号,然后为每人偶手里都握着一个令牌,令牌上有一个数字(随机生成的),和下个倒霉人偶有关。
- 第一个击的是第一个人偶,下次射击的从被打倒的人偶以后的第一个人偶开始数,往后数第 ai 个(是为其令牌上写明的数字数)。注意人偶被打到则出列。
- 以上过程直到所有人都出列为止。
- ★数据输入
- 第 1 行一个整数 n(1<=n<=3000),代表人偶数,
- 5
- 第 2 行有 n 个空格隔开的整数代表按时间顺序被打倒的人偶的编号(1<=ai<=1000)。
- 1 3 2 4 3
- ★数据输出
- 1 2 5 3 4
- 被打倒的人偶的编号
- */