A. Array Balancing
题意:给定一个操作,可以交换 a i ai ai 和 b i bi bi 使得两序列相邻绝对值的和最小
做法:小的放上面,大的放下面
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n;
vector<int> a(n), b(n);
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++) cin >> b[i];
for (int i = 0; i < n; i++) if (a[i] > b[i]) swap(a[i], b[i]);
int ans = 0;
for (int i = 0; i < n - 1; i++) ans += abs(a[i] - a[i + 1]);
for (int i = 0; i < n - 1; i++) ans += abs(b[i] - b[i + 1]);
cout << ans << '\n';
}
return 0;
}
B. Getting Zero
题意:给你两个操作和 n n n 个数,问你将第 i i i 个数变成 0 0 0 的最少操作次数
做法:可以考虑记忆化搜索预处理出来所有答案然后输出,也可以BFS直接干
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 32768;
bool st[40000];
int bfs(int x)
{
memset(st, false, sizeof st);
queue<pair<int, int>> q;
q.push({x, 0});
st[x] = true;
while (q.size())
{
auto t = q.front();
q.pop();
int x = t.first;
int y = t.second;
if (x == 0) return y;
if (!st[(x + 1) % mod])
{
st[(x + 1) % mod] = true;
q.push({(x + 1) % mod, y + 1});
}
if (!st[(x * 2) % mod])
{
st[(x * 2) % mod] = true;
q.push({(x * 2) % mod, y + 1});
}
}
}
signed main()
{
int n;
cin >> n;
map<int, int> mp;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
// 如果没搜过就搜,搜过了直接输出答案
if (!mp.count(x)) mp[x] = bfs(x);
cout << mp[x] << " ";
}
return 0;
}
C. Water the Trees
题意:奇数天浇水长1,偶数天浇水长2,问多少天可以让所有树都一样高
做法:二分答案,注意最终的高度只可能是最初所有树高度的 m a x max max 或 m a x + 1 max + 1 max+1
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
int maxx = *max_element(a.begin(), a.end());
int ans = 1e18;
for (int mx : {maxx, maxx + 1})
{
int num1 = 0, sum = 0;
for (int i = 0; i < n; i++)
{
if ((mx - a[i]) % 2) num1++;
sum += mx - a[i];
}
int l = 0, r = 1e18;
while (l < r)
{
int mid = l + r >> 1;
int cnt2 = mid / 2, cnt1 = mid - mid / 2;
if (cnt1 >= num1 && cnt1 + cnt2 * 2 >= sum) r = mid;
else l = mid + 1;
}
ans = min(l, ans);
}
cout << ans << '\n';
}
return 0;
}