「Codeforces」B. Avoid Local Maximums
B. Avoid Local Maximums
https://codeforces.com/contest/1635/problem/B
题目描述
你有一个数组,数组中的每一个元素都是整形数值( 1 ≤ a i ≤ 1 0 9 1\leq a_i \leq 10^9 1≤ai≤109 ),你可以多次对数组进行操作,每次操作你都可以使用一个大小为 1 ≤ x ≤ 1 0 9 1 \leq x \leq10^9 1≤x≤109 之间的任意数字替换数组中的 a i a_i ai 。
求:使用最少的操作,使数组内不包含局部最大值。
局部最大值:若 a i a_i ai 大于相邻的两个元素,则它就是局部最大值。
输入描述
每个测试包含多个测试用例。 第一行将包含一个整数 t (1≤t≤10000)——测试用例的数量。 然后是 t 个测试用例。
每个测试用例的第一行包含一个整数 n (2≤n≤2⋅105) — 数组 a 的大小。
每个测试用例的第二行包含 n 个整数 a1,a2,…,an (1≤ai≤109),数组的元素。
保证所有测试用例的 n 之和不超过 2⋅105。
输出描述
对于每个测试用例,首先输出一个包含单个整数 m 的行——所需的最小操作数。 然后输出一行由 n 个整数组成的行——操作后的结果数组。 请注意,此数组应该与初始数组的 m 个元素完全不同。
如果有多个答案,打印任何一个。
样例
#1
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 3
在第一个示例中,数组不包含局部最大值,因此我们不需要执行操作。
在第二个示例中,我们可以将 a2 更改为 3,则数组没有局部最大值。
提示
解析
讲真,虽然过了,不过就是做法好像比较笨(不管,反正我过了,哈哈哈)。
1 2 3 1 // 3 是局部最大值
1 3 3 1 // 更新前面的 2 变成 3
1 2 1 2 1 // 两个 2 都是局部最大值
1 2 2 2 1 // 修改中间的 1 为 2(执行一次)
1 1 1 1 1 // 修改两个 2 为 1(执行两次)
根据局部最大值的定义,可以知道局部最大值若有多个,一定是相隔开的,两两之间至少隔了一个元素,那么我们只需要让这个元素修改为左右两边最大的那一方就可以啦。
AC Code
import java.util.*;
import java.io.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
public static void main(String[] args) throws Exception {
int T = nextInt();
while(T-- != 0) {
int n = nextInt();
int[] A = new int[n];
boolean[] vis = new boolean[n];
for(int i = 0; i < n; i++) A[i] = nextInt();
for(int i = 1; i < n - 1; i++) { // 筛选局部最大值
if(A[i] > A[i-1] && A[i] > A[i+1]) {
vis[i] = true;
}
}
int total = 0; // 统计执行次数
for(int i = 1; i < n - 1; i++) { // 修改局部最大值
if(i + 2 < n && vis[i] && vis[i+2]) { // 若两个局部最大值相隔一格,则修改中间元素
total++;
A[i + 1] = Math.max(A[i], A[i + 2]);
vis[i] = false;
vis[i + 2] = false;
continue;
}
if(vis[i]){ // 单个局部最大值
total++;
A[i-1] = A[i];
vis[i] = false;
}
}
out.println(total);
for(int i = 0; i < n; i++) out.print(A[i] + " ");
out.println();
}
out.flush();
}
public static int nextInt() throws Exception {
st.nextToken();
return (int) st.nval;
}
public static String nextStr() throws Exception {
st.nextToken();
return st.sval;
}
}