Codeforces Round 931 (Div. 2)
Codeforces Round 931 (Div. 2)
A - Too Min Too Max
解题思路:
最大、最小、次大、次小。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
typedef double db;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
void solve()
{
int n;
cin >> n;
vector<ll> a(n + 1), b(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
ll ans = 0;
sort(a.begin() + 1, a.end());
ans = abs(a[n] - a[1]) + abs(a[1] - a[n - 1]) + abs(a[n - 1] - a[2]) + abs(a[2] - a[n]);
cout << ans << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
B - Yet Another Coin Problem
解题思路:
\(30\)以内的数字用背包求最优凑法,\(30\)往上的\(15\)填到只剩下\(30\)以内。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
typedef double db;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
ll f[100];
void solve()
{
ll n;
cin >> n;
ll cnt = 0;
if (n / 15 >= 2)
{
cnt += n / 15 - 1;
n -= (n / 15 - 1) * 15;
}
cout << cnt + f[n] << endl;
}
int main()
{
for (int i = 1; i <= 99; i++)
{
f[i] = 1e9;
}
f[0] = 0;
for (int i = 1; i <= 99; i++)
{
int cur = 15;
for (int j = 5; j >= 1; j--)
{
if (i >= cur)
{
f[i] = min(f[i - cur] + 1, f[i]);
}
cur -= j;
}
}
// for (int i = 1; i <= 99; i++)
// {
// cout << i << ' ' << f[i] << endl;
// }
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
C - Find a Mine
解题思路:
第一次询问\((1, 1)\):存在一个答案在\(x + y = d+ 2\)这个对角线上。
求该对角线右上角\((x_1, y_1)\),左下角\((x_2,y_2)\)。
询问\((x_1,y_1)\):
- 如果返回是奇数,说明存在不在该对角线上的地雷距离\((x_1,y_1)\)更近。选择询问\((x_2,y_2)\),答案为\((x_2 + \frac{d}{2},y_2 + \frac{d}{2})\)。
- 如果返回是偶数,询问\((x_1 + \frac{d}{2},y_1 + \frac{d}{2})\),如果返回距离为\(0\)说明找到一个解;否则说明存在不在该对角线上的地雷距离\((x_1,y_1)\)更近,同上,转为询问\((x_2,y_2)\)。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
typedef double db;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
void ask(int x, int y)
{
cout << "?" << ' ' << x << ' ' << y << endl;
cout.flush();
}
void solve()
{
int n, m;
cin >> n >> m;
ask(1, 1);
ll d;
cin >> d;
if (d == 0)
{
cout << "!" << ' ' << 1 << ' ' << 1 << endl;
return;
}
int x = 1;
int y = 1;
if (m - y >= d)
{
y += d;
}
else
{
int t = d;
t -= m - y;
y = m;
x += t;
}
int a = 1;
int b = 1;
if (n - a >= d)
{
a += d;
}
else
{
int t = d;
t -= n - a;
a = n;
b += t;
}
ask(x, y);
cin >> d;
if (d == 0)
{
cout << "!" << ' ' << x << ' ' << y << endl;
return;
}
if (d & 1)
{
ask(a, b);
cin >> d;
if (d == 0)
{
cout << "!" << ' ' << a << ' ' << b << endl;
return;
}
a -= d / 2;
b += d / 2;
cout << "!" << ' ' << a << ' ' << b << endl;
}
else
{
x += d / 2;
y -= d / 2;
ask(x, y);
cin >> d;
if (d == 0)
{
cout << "!" << ' ' << x << ' ' << y << endl;
}
else
{
ask(a, b);
cin >> d;
a -= d / 2;
b += d / 2;
cout << "!" << ' ' << a << ' ' << b << endl;
}
}
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
D1 - XOR Break --- Solo Version
解题思路:
若\((n \oplus m) < n\),那么一步直接变。
否则,对\(n\)进行变换,使得\((n \oplus m) < n\)。如果存在,改变换只需要一步。
如果\((n)_2 = 11011,(m)_2 = 00100\)这种形式,我们可以将\(n \to 10111\),即将距离\(n\)次高位\(1\)变为\(0\),然后低位全部变成\(1\)。此时,\(n \to x\),所有\(x \oplus m < x\)的\(m\)都可直接变换,即运用题目法则\(x \to y\)。
如果\(m\)的最高位\(1\)仅低于\(n\)的最高位\(1\),而不小于等于\(n\)的次高位\(1\)。我们发现,总是无法满足变换条件。
若我们先异或了\(m\)最高位的\(1\),\(x \oplus y > x\);
若我们先异或了\(n\)最高位的\(1\),\(x \oplus y < m\),后续一定也无法变为\(m\);
如果我们同时处理二者最高位\(1\),那么\(y > x\)不符合操作条件。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
typedef double db;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
ll lowbit(ll x)
{
return x & -x;
}
void solve()
{
ll n, m;
cin >> n >> m;
if ((n ^ m) < n)
{
cout << 1 << endl;
cout << n << ' ' << m << endl;
return;
}
vector<ll> ans;
ans.emplace_back(n);
ll x = n;
vector<ll> b;
for (int i = 62; i >= 0; i--)
{
if (x >> i & 1)
{
b.emplace_back(i);
}
if (m >> i & 1)
{
if (b.size() <= 1)
{
puts("-1");
return;
}
auto t = b.back();
b.pop_back();
ll val = (1ll << t) - 1;
for (auto a : b)
{
val += (1ll << a);
}
ans.emplace_back(val);
ans.emplace_back(m);
break;
}
}
cout << ans.size() - 1 << endl;
for (auto x : ans)
{
cout << x << ' ';
}
cout << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}

浙公网安备 33010602011771号