目录
大意:
题目如下:
You are given an array aa of size nn. Each element in this array is an integer between 11 and 10^9109.
You can perform several operations to this array. During an operation, you can replace an element in the array with any integer between 11 and 10^9109.
Output the minimum number of operations needed such that the resulting array doesn't contain any local maximums, and the resulting array after the operations.
An element a_iai is a local maximum if it is strictly larger than both of its neighbors (that is, a_i > a_{i - 1}ai>ai−1 and a_i > a_{i + 1}ai>ai+1). Since a_1a1 and a_nan have only one neighbor each, they will never be a local maximum.
Input
Each test contains multiple test cases. The first line will contain a single integer tt (1 \leq t \leq 10000)(1≤t≤10000) — the number of test cases. Then tt test cases follow.
The first line of each test case contains a single integer nn (2 \leq n \leq 2 \cdot 10^5)(2≤n≤2⋅105) — the size of the array aa.
The second line of each test case contains nn integers a_1, a_2, \ldots ,a_na1,a2,…,an (1 \leq a_i \leq 10^9)(1≤ai≤109), the elements of array.
It is guaranteed that the sum of nn over all test cases does not exceed 2 \cdot 10^52⋅105.
Output
For each test case, first output a line containing a single integer mm — minimum number of operations required. Then ouput a line consist of nn integers — the resulting array after the operations. Note that this array should differ in exactly mm elements from the initial array.
If there are multiple answers, print any.
Sample 1
Input Output 5 3 2 1 2 4 1 2 3 1 5 1 2 1 2 1 9 1 2 1 3 2 3 1 2 1 9 2 1 3 1 3 1 3 1 3 0 2 1 2 1 1 3 3 1 1 1 2 2 2 1 2 1 2 3 3 2 3 3 2 1 2 2 1 3 3 3 1 1 1 3Note
In the first example, the array contains no local maximum, so we don't need to perform operations.
In the second example, we can change a_2a2 to 33, then the array don't have local maximums.
大意:
给出n个m长度的数组,每个数字两侧的数字都不能大于中间的数字。可以将其改动使其符合题意,记录改动次数,并输出改动次数和改动完成的数组。
代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include <cstring>//代码需要的库
using namespace std;
int key[9900001];
int n,m,j,mid;//定义常量
int main()
{
memset(key,0x3f,sizeof(key));//使数组所有的数都变为无穷大,可避免误判第一个和最后一个元素
int s;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&m);
for( j=0;j<m;j++)
{
scanf("%d",&key[j]);
s=0;//计数器,记录改变次数,并在输入新数组时更新
}
for(mid=1;mid<=m-2;mid++)//,通过比较两边
{
if(key[mid]>key[mid-1]&&key[mid]>key[mid+1])//找到峰值
{
if(key[mid+2]>key[mid+1]&&key[mid+2]>key[mid+3])//判断接下来的两个数,是否组成第二个峰值
{
key[mid+1]=max(key[mid],key[mid+2]);//使峰值变成两边比较大的数值,消除山峰
s++;//纪录操作数
mid=mid+2;//使判定点推进2位,避免重复判定
}else
{
key[mid]=max(key[mid-1],key[mid+1]);//判定只有一个山峰,消除峰值
s++;//纪录操作数
}
}
}
printf("%d\n",s);//输出操作数
for(int k=0;k<m;k++)//输出改变后的数组
{
printf("%d ",key[k]);
if(k==m-1)printf("\n");//记得换行
}
}
return 0;
}
注意事项:
1.为什么山峰改变为较大的两边较大的数值?
可以避免改变后与另一边连起来再次出现峰值。
2.数组为什么要变为无穷大?
避免开头与结尾因为数组空位为0,而造成程序误判。