Codeforces Round #746 (Div. 2)(A,B,C)
Posted H-w-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #746 (Div. 2)(A,B,C)相关的知识,希望对你有一定的参考价值。
Codeforces_Round#746(Div.2)
A.Gamer_Hemose
题意:
一个 B o s s Boss Boss 的血量为 m m m,有 n n n把武器,每次能够使用一把武器,每把武器不能连续使用,问最少要几次才能杀掉 B o s s Boss Boss
思路:
选两个伤害最大的武器,交替使用。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
const int mod = 1e9+7;
ll a[N];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while(t--) {
int n, m;
cin >> n >> m;
for(int i=1; i<=n; i++) {
cin >> a[i];
}
sort(a+1, a+1+n, greater<int>());
int x = a[1], y = a[2];
int ans = m / (x + y) * 2, tmp = m % (x + y);
if(tmp > 0) {
if(tmp <= x) ans++;
else ans += 2;
}
cout << ans << endl;
}
}
B.Hemose_Shopping
题意:
给出一个数组 a a a,两个整数 n n n, x x x,你能交换任意的满足 1 ≤ i , j ≤ n 1\\le i,j \\le n 1≤i,j≤n且 ∣ i − j ∣ ≥ x |i-j|\\ge x ∣i−j∣≥x的 a i , a j a_i,a_j ai,aj,问最后能否将序列排序。
思路:
将能够交换的数据放在同一堆,我们能够发现,当 n / x ≥ 2 n/x\\ge 2 n/x≥2时,所有数一定在同一堆。
否则,只有中间一段数据是不能交换的,所以我们要 c h e c k check check排序完后的序列,在中间这一段是不是完全相等,是的话,说明能够排好序,否则不能。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
const int mod = 1e9+7;
int a[N], b[N], n, m;
bool check() {
int x = n-m;
for(int i=x+1; i<1+m; i++) {
if(a[i] != b[i]) return false;
}
return true;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while(t--) {
cin >> n >> m;
for(int i=1; i<=n; i++) {
cin >> a[i];
b[i] = a[i];
}
sort(a+1, a+1+n);
if(n / m >= 2) {
cout << "YES\\n";
}
else {
if(check()) cout << "YES\\n";
else cout << "NO\\n";
}
}
}
C.Bakry_and_Partitioning
题意:
给出一棵n个节点的树,每个点都有一个权值,树的权值为每个点权值的异或和,切割 x x x条边( x ∈ [ 1 , k − 1 ] x\\in[1,k-1] x∈[1,k−1])
问是否存在一种方法使得切割出来的每个树的权值都相等。
思路:
首先我们考虑切割前的树的权值为 0 0 0,可以想到这是一定有解的。
割前树的权值为m( m ≠ 0 m\\neq 0 m=0),如果有解,那么一定可以切割成三棵树,每棵树的权值都是 m m m。
做法:
用一个数组 b b b表示权值, b i b_i bi表示以 i i i为根节点的子树的权值。
d f s dfs dfs遍历整颗树,找到某个节点存在两个子树的权值是m,或者当前节点的权值是 0 0 0,存在至少一个子树的权值是m。
否则,不存在。
(补充:注意输入的k,最多只能删除 k − 1 k-1 k−1条边)
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;//双向边,所以开两倍。
const int mod = 1e9+7;
int a[N], b[N], n, m, resu;
int head[N], Ne[N], to[N], cnt = 0;
void add(int x, int y) {
to[++cnt] = y;
Ne[cnt] = head[x];
head[x] = cnt;
}
int f = 0;
bool dfs2(int x, int fa) {
int tot = 0;
b[x] = a[x];
for(int i=head[x]; i; i=Ne[i]) {
if(to[i] == fa) continue;
if(dfs2(to[i], x)) tot++;
b[x] ^= b[to[i]];
}
if(tot >= 2 || (tot == 1 && b[x] == 0)) {
f = 1;
}
if(tot >= 1 || (b[x] == resu)) return true;
else return false;
}
bool solve2() {
dfs2(1, -1);
if(f) return true;
return false;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while(t--) {
memset(head, 0, sizeof head);
cnt = 0, f = 0, resu = 0;
cin >> n >> m;
for(int i=1; i<=n; i++) {
cin >> a[i];
resu ^= a[i];
}
int x, y;
for(int i=1; i<n; i++) {
cin >> x >> y;
add(x, y);
add(y, x);
}
if(resu == 0) {
cout << "YES\\n";
}
else {
if(m > 2 && solve2()) cout << "YES\\n";
else cout << "NO\\n";
}
}
}
以上是关于Codeforces Round #746 (Div. 2)(A,B,C)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #746 (Div. 2)(A,B,C)
Codeforces Round #746 (Div. 2) C. Bakry and Partitioning
Codeforces Round #746 (Div. 2) 题解
Codeforces Round #746 (Div. 2)A-C