Codeforces Round 1042 (Div. 3)
给你两个长度为n的数组a,b在每次迭代中:1.对于任意一个aibi的下标i,会让ai−12.对于任意一个aibi的下标i,会让ai1如果操作1无法执行,迭代终止问会进行几次迭代。
A. Lever


题目大意
给你两个长度为n的数组a,b
在每次迭代中:
1.对于任意一个ai>bia_i>b_iai>bi的下标i,会让ai−1a_i-1ai−1
2.对于任意一个ai<bia_i<b_iai<bi的下标i,会让ai+1a_i+1ai+1
如果操作1无法执行,迭代终止
问会进行几次迭代
思路
迭代的次数为对于所有ai>bia_i>b_iai>bi的下标i,ai−bia_i-b_iai−bi的总和
操作2对操作1没有影响
// Author: zengyz
// 2025-08-13 16:55
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
int n;
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];
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (a[i] > b[i])
cnt += a[i] - b[i];
}
cout << cnt + 1 << endl;
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _T = 1;
cin >> _T;
while (_T--)
{
solve();
}
return 0;
}
B. Alternating Series


题目大意
我们称一个数组是好的,当
对于任意i,有ai∗ai+1<0a_i*a_{i+1}<0ai∗ai+1<0
且任意连续子数组的和为正数
给你数组长度n,构造字典序最小的好的数组
思路
首先要求字典序最小,所以我们让负数都为-1(这样对应的正数也是最小的),然后考虑如何构造
首先对于任意i,有ai∗ai+1<0a_i*a_{i+1}<0ai∗ai+1<0,所以数组内肯定是一正一负
然后考虑样例2的情况,中间一个正数,左右两个负数,那么正数最小的情况是3
那么按-1 3 -1 3。。。的情况构造出来的一定是一个好的数组
考虑数组长度为偶数时 最后一位为2同样满足条件,且字典序更小
所以当数组为奇数时,-1 3 -1 3。。。且以-1 结尾
当数组长度为偶数时,以2结尾
// Author: zengyz
// 2025-08-13 16:58
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
int n;
cin >> n;
if (n % 2)
{
for (int i = 1; i <= n / 2; i++)
{
cout << -1 << " " << 3 << " ";
}
cout << -1 << endl;
}
else
{
for (int i = 1; i < n / 2; i++)
{
cout << -1 << " " << 3 << " ";
}
cout << -1 << " " << 2 << endl;
}
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _T = 1;
cin >> _T;
while (_T--)
{
solve();
}
return 0;
}
C. Make it Equal

题目大意
给你两个可重集合S,T
你可以从S中任意选择一个元素x,令x=x+k或者|x-k |
问是否能让S和T相等
思路
令x=x+k或者|x-k |可以变成余数为x%k或者k - (x%k)的任何数
所以我们只要逐个判断一下T中所有元素的x%k或k - (x%k)是否与S中对应即可 ,
用mp存储余数,操作S同时增加x%k或者k - (x%k)的次数
操作T同时删除x%k或者k - (x%k)的次数,如果二者都为0说明无法相等
// Author: zengyz
// 2025-08-13 17:00
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
int n, k;
cin >> n >> k;
vector<int> s(n), t(n);
map<int, int> mp;
for (int i = 0; i < n; i++)
{
cin >> s[i];
mp[s[i] % k]++;
mp[k-(s[i]%k)]++;
}
bool flag = true;
for (int i = 0; i < n; i++)
{
cin >> t[i];
if (mp[t[i] % k] == 0 && mp[k-(t[i]%k)] == 0)
{
flag = false;
}
else
{
mp[t[i] % k]--;
mp[k-(t[i]%k)]--;
}
}
if (flag)
{
cout << "YES" << endl;
}
else
cout << "NO" << endl;
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _T = 1;
cin >> _T;
while (_T--)
{
solve();
}
return 0;
}
D. Arboris Contractio


题目大意
给你一棵树,你可以进行如下操作:
选择两个节点u,v
删除这两个节点之间的路径上的所有边,对于这条路径上的所有节点t
构建新的边(u,t)
问最少经过几次操作,可以使得树上任意两个节点的最短距离最小
思路
要使得任意两个节点的最短距离最小,那么这棵树一定是一棵星型的树,除一个中心结点外,其他结点都是它的叶子结点,这样任意两个节点的最短距离为2
那么我们要通过操作实现,我们就要找到一个结点t,然后对于这个结点t,将其他叶子结点和这个结点t进行操作,就可以得到这样一棵树,那么最小操作次数就是要找到这样一个t,它的子结点的叶子结点最多
我们遍历所有叶子结点的父节点并为其打上标记
找到叶子结点最多的父节点,操作次数就是总叶子结点数减去最多叶子的结点 数
// Author: zengyz
// 2025-08-13 17:21
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
int n;
cin >> n;
vector<vector<int>> edge(n + 1);
map<int, int> mp;
for (int i = 1; i < n; i++)
{
int u, v;
cin >> u >> v;
edge[u].push_back(v);
edge[v].push_back(u);
}
if(n==2)
{
cout<<0<<endl;
return;
}
int cnt=0;
for (int i = 1; i <= n; i++)
{
if (edge[i].size() == 1)
{
mp[edge[i][0]]++;
cnt++;
}
}
int maxx=0;
for(int i=1;i<=n;i++)
maxx=max(maxx,mp[i]);
cout<<cnt-maxx<<endl;
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _T = 1;
cin >> _T;
while (_T--)
{
solve();
}
return 0;
}
E. Adjacent XOR


题目大意
给你两个数组a,b
对于数组a的每个下标i,你可以进行至多一次操作
使得ai=ai⊕ai+1a_i=a_i \oplus a_{i+1}ai=ai⊕ai+1
问是否能通过操作将a变成b
思路
对于每个aia_iai
首先判断ai是否等于bia_i是否等于b_iai是否等于bi
如果不相等,那么从左到右考虑当前的i,判断ai⊕ai+1是否=bia_i \oplus a_{i+1}是否=b_iai⊕ai+1是否=bi
如果不相等,那么从右到左考虑当前的i,判断ai⊕bi+1是否=bia_i \oplus b_{i+1}是否=b_iai⊕bi+1是否=bi(因为ai+1a_{i+1}ai+1最后需要变成b_{i+1},我们先操作ai+1a_{i+1}ai+1
如果以上三种情况都不行,那么输出no
记得特判最后一个元素
// Author: zengyz
// 2025-08-13 17:29
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
int n;
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];
bool flag = true;
if (a[n - 1] != b[n - 1])
{
cout << "NO" << endl;
return;
}
for (int i = n - 2; i >= 0; i--)
{
if (a[i] != b[i])
{
if ((a[i] ^ a[i + 1]) != b[i])
{
if ((a[i] ^ b[i + 1]) != b[i])
{
flag = false;
break;
}
}
}
}
if (flag)
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _T = 1;
cin >> _T;
while (_T--)
{
solve();
}
return 0;
}
更多推荐


所有评论(0)