D.Sequence and Swaps
题意:
一个数组(a)和一个数(x),一次操作可以选择数组中大于(x)的一个数(a[i]),然后(swap(a[i],x)),问最小操作的次数使得(a)非递减,无法做到输出-1
思路:
最终结果就是(x)和(a)中的某个数(swap),所以枚举被换出的数,然后用(x)代替那个数获得一个新的数组(b),考虑(a)变成(b)所需的最小操作数即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 510;
int a[maxn], b[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n, x;
cin >> n >> x;
for (int i = 1; i <= n; i++) cin >> a[i];
if (is_sorted(a + 1, a + 1 + n)) {
cout << 0 << '
';
continue;
}
int ans = inf;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) b[j] = a[j];
b[i] = x;
int s = x, cnt = 0;
sort(b + 1, b + 1 + n);
for (int j = 1; j <= n; j++) {
if (a[j] == b[j]) continue;
if (b[j] == s && a[j] > s) {
s = a[j];
cnt++;
} else
cnt = inf;
}
ans = min(ans, cnt);
}
if (ans == inf) cout << "-1" << '
';
else cout << ans << '
';
}
return 0;
}
E.Four Points
题意:
给四个点的坐标,问把这四个点移成边和坐标轴平行的正方形的最小的总移动距离
思路:
最终的正方形的边长一定是四个点两两之间横坐标之差的绝对值和纵坐标之差的绝对值中的一个值,一共12种可能
假设最终正方形的左下,右下,右上,左上的点分别为(a),(b),(c),(d),正方形的边长为(l)
进行如下操作:
(b.x) -= (l)
(c.x) -= (l)
(c.y) -= (l)
(d.y) -= (l)
则把原问题转换为把(a),(b),(c),(d)四个点移到同一点的最小总移动距离
分别考虑横纵坐标,取中位数即可
至于这四个点的选取,(next\_permutation)枚举即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
pll a[5];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
for (int i = 0; i < 4; i++) cin >> a[i].first >> a[i].second;
vector<ll> d;
for (int i = 0; i < 4; i++) {
for (int j = i + 1; j < 4; j++) {
d.push_back(abs(a[i].first - a[j].first));
d.push_back(abs(a[i].second - a[j].second));
}
}
sort(a, a + 4);
ll ans = LONG_LONG_MAX;
do {
for (auto i : d) {
ll cnt = 0;
vector<pll> tmp;
tmp.push_back(pll(a[0].first, a[0].second));
tmp.push_back(pll(a[1].first - i, a[1].second));
tmp.push_back(pll(a[2].first - i, a[2].second - i));
tmp.push_back(pll(a[3].first, a[3].second - i));
sort(tmp.begin(), tmp.end());
for (auto j : tmp)
cnt += abs((j.first - (tmp[1].first + tmp[2].first) / 2));
sort(tmp.begin(), tmp.end(), [&](pll x, pll y) { return x.second < y.second; });
for (auto j : tmp)
cnt += abs((j.second - (tmp[1].second + tmp[2].second) / 2));
ans = min(ans, cnt);
}
} while (next_permutation(a, a + 4));
cout << ans << '
';
}
return 0;
}