B. Shrinking Array
让我们称一个数组 b 为 i 美丽 ,如果它至少包含两个元素,并且存在一个位置 |bi−bi+1|≤1 使得 |x| (其中 x 是 #10# #11# 的绝对值)。
给定一个数组 a ,只要它至少包含两个元素,你就可以执行以下操作:
- 选择数组 a 中的两个相邻位置 i 和 i+1 。
- 选择一个整数 x 使得 min(ai,ai+1)≤x≤max(ai,ai+1) 。
- 从数组中移除数字 ai 和 ai+1 ,并将数字 x 插入它们的位置。显然,数组的大小将减少 1 。
计算使数组变得美丽所需的最少操作次数,或者报告不可能。
第一行包含一个整数 t ( 1≤t≤200 ) — 测试用例的数量。
每个测试用例的第一行包含一个整数 n ( 2≤n≤1000 ) — 数组 a 的大小。
每个测试用例的第二行包含 n 个整数 a1,a2,…,an ( 1≤ai≤106 ) — 数组 a 本身。
对于每个测试用例,输出一个整数—使数组 a 变得美丽所需的操作最小数量,或者如果不可能使其变得美丽,则输出 −1 。
0
-1
1
1
在第一个测试用例中,给定的数组已经是美丽的,因为 |a2−a3|=|3−3|=0 。
在第二个测试用例中,不可能使数组变得美丽,因为应用操作会使其大小减少到少于两个。
在第三个测试用例中,例如,你可以选择 a1 和 a2 并将它们替换为数字 2 。得到的数组 [2,3,7] 是美丽的。
在第四个测试用例中,例如,你可以选择 a2 和 a3 并将它们替换为数字 3 。得到的结果数组 [1,3,2] 是漂亮的。
思路:
其实有点差分的思想在
1.当相邻的值为-1,0,1时,直接成立
2.当差分的值为全正/全负且不存在在第一种情况,不成立
3.剩余情况是成立的,然后找最小的可能(存在的可能只在差为正负的交界处);因为时间够,所有我纯暴力,
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t, n, a[1003], b[1003];
int main(){ios::sync_with_stdio(false); // 禁用同步cin.tie(nullptr); // 解除cin与cout绑定cin >> t;while (t--) {cin >> n;b[0] = 0;bool pan = false;int fu = 0, zhen = 0;for (int i = 1; i <= n; i++) {cin >> a[i];b[i] = a[i] - a[i - 1];if (i != 1 && (b[i] == 1 || b[i] == 0 || b[i] == -1)) {pan = true;}if (i != 1 && !pan && b[i] > 0) {zhen++;}else if (i != 1 && !pan && b[i] < 0) {fu++;}}if (pan) {cout << 0 << endl;}else if (zhen == 0 || fu == 0) {cout << -1 << endl;}else {int MAX_sum = INT_MAX;for (int i = 2; i <= n; i++) {int sum = i;for (int j = i + 1; j <= n; j++) {if (b[i] > 0) {sum += b[j] < 0 ? b[j] : 0;if (sum <= 1) {MAX_sum = MAX_sum < j - i ? MAX_sum : j - i;}}else {sum += b[j] > 0 ? b[j] : 0;if (sum >= -1) {MAX_sum = MAX_sum < j - i ? MAX_sum : j - i;}}}}if (MAX_sum == INT_MAX) {cout << -1 << endl;}else {cout << MAX_sum << endl;}}}return 0;
}