Dashboard - Codeforces Round 896 (Div. 2) - Codeforces
A. Make It Zero
思维,会发现如果长度为偶数进行两次操作即可,第一次将所有数变为相同的数,将这些相同的数异或,由于长度为偶数,所以最后以获得结果为0。如果长度为奇数,进行4此操作即可,第一次操作为将前n - 1个数给变为0,最后还有一个数没有变为0,可以将那个数与前一个0组成一个偶数进行变换
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
void solve()
{
int n, a[N], l[N], r[N], ans, cnt;
ans = 0, cnt = 0;
cin >> n;
for(int i = 1; i <= n; i ++)cin >> a[i];
if((n % 2) == 0)
{
cout << 2 << '\n';
cout << 1 << ' ' << n << '\n';
cout << 1 << ' ' << n << '\n';
}
else
{
cout << 4 << '\n';
cout << 1 << ' ' << n - 1 << '\n';
cout << 1 << ' ' << n - 1 << '\n';
cout << n - 1 << ' ' << n << '\n';
cout << n - 1 << ' ' << n << '\n';
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
B. 2D Traveling
可知如果没有大城市,a到b的最少费用为a到b,如果ab之间有大城市,a到b的最少费用为a到大城市的费用加上b到大城市的费用与a到b的费用取最小值
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10, inf = 0x3f3f3f;
pair<ll, ll> p[N];
#define x first
#define y second
void solve()
{
int n, k, a, b;
cin >> n >> k >> a >> b;
for(ll i = 1; i <= n; i ++)
{
cin >> p[i].x >> p[i].y;
}
ll dis1 = 1e18, dis2 = 1e18;
for(ll i = 1; i <= k; i ++)
{
dis1 = min(dis1, abs(p[i].x - p[a].x) + abs(p[i].y - p[a].y));
dis2 = min(dis2, abs(p[i].x - p[b].x) + abs(p[i].y - p[b].y));
}
cout << min(dis1 + dis2, abs(p[a].x - p[b].x) + abs(p[a].y - p[b].y)) << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
C. Fill in the Matrix
由题意知每一行都为全排列,每一列都有一个不能出现的数,要将这些数错开,可以每次将一列数进行左移,如果已经实现答案值,其他乱写即可,特判当m == 1时这一列最小也是0,没有结果,故输出0
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
void solve()
{
int n, m, a[N];
cin >> n >> m;
if(m == 1)
{
cout << 0 << '\n';
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
cout << 0 << ' ';
}
cout << '\n';
}
return;
}
int ans = min(n + 1, m);
cout << ans << '\n';
int cnt = 0;
for(int i = 0; i < m; i ++)a[i] = i;
int k = n;
while(k --)
{
for(int i = cnt; i < m; i ++)
{
cout << a[i] << ' ';
}
for(int j = 0; j < cnt; j ++)
{
cout << a[j] << ' ';
}
cout << '\n';
if(cnt < m - 2)cnt ++;
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
D1. Candy Party (Easy Version)
需要每个人都给出和拿到糖果,并且每个人的糖果最后数目一样。
如果每个人糖果数目一样那么这个数就是平均值,如果最开始糖果数是平均值的就不需要再变化了,因为可以把这个糖果给出去再给回来,最后还是没有发生变化。
令sum为整个个数组的和,只有当sum % n == 0,才存在一种合法方案,令avg为平均数,固设d = vag - x为这个数与平均数的差值,由于我们需要每个人拿上一个糖果并且每个人要给出一个糖果,所以对于每个人我们肯定会发生的变化为,所以为了让x变为vag,必须要满足,这样的答案就具有了唯一性,(两个二次幂数相减得到的结果一定不会存在相同的情况。
由于每个人都会收到恰好一个人的糖果,并且会给出恰好一个人的糖果,我们假设对于某一个人如果需要收到x个糖果并且给出x个糖果来达到平均值,那么必然需要有一个给出 个糖果的人和一个收到 个糖果的人与之对应。
对于每一个元素x,我们求出其对应的(j,k)满足上面的等式,并统计各个二次幂数出现次数的奇偶性,如果一个二次幂出现奇数次,则不合法。
部分通过的代码:(不知道那里的问题)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 +10;
ll n, a[N], cnt[65];
void solve()
{
ll sum = 0;
cin >> n;
for(ll i = 1; i <= n; i ++)
{
cin >> a[i];
sum += a[i];
}
if(sum % n)
{
cout << "NO" << '\n';
return;
}
ll vag = sum / n, flag = 0;
for(ll i = 1; i <= n; i ++)
{
ll st = 0;
for(ll j = 0; j <= 60; j ++)
{
for(ll k = 0; k <= 60; k ++)
{
if(a[i] + (1ll << j) - (1ll << k) == vag)
{
st = 1,cnt[j] ^= 1, cnt[k] ^= 1;
}
}
}
if(!st)flag = 1;
}
for(ll i = 0; i <= 60; i ++)
{
if(cnt[i] > 0)flag = 1;
cnt[i] = 0;
}
if(flag)cout << "NO" << '\n';
else cout << "YES" << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
ll t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}