第一题 ARC143 A
题目解析
首先,操作1可以演变成让 一个数加 1 1 1 其余数不变。根据这条操作所以代码表示:
#include<bits/stdc++.h>
using namespace std;
long long t,a[3];
int main(){
scanf("%lld %lld %lld",&a[0],&a[1],&a[2]);
sort(a,a+3);
a[2]-=a[0];
a[1]-=a[0];
if(a[0]<a[2]-a[1])printf("-1\n");
else printf("%lld\n",(a[0]-(a[2]-a[1]))+a[2]+(a[2]-a[1]));
}
第二题 ABC226 E
题目解析
单看一个连通块,要满足所有点的出度都为
1
1
1,说明连通块必须有环,而且只能存在一个环,如果存在多个环就会使得某个点的出度
>
1
>1
>1。
那么总结起来就是每个连通块的点数和边数必须相等
每个连通块显然只有两种方案安排边的方向,因此当所有连通块都满足的情况下,设连通块个数
n
n
n ,答案就是 $ 2^n $
这个可以用并查集来求
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 2e5 + 9;
const int mod = 998244353;
ll n, m;
int f[maxn];
int x[maxn], y[maxn];
int ecnt[maxn], vcnt[maxn];
int find(int x){
return f[x] == x ? x : f[x] = find(f[x]);
}
void merge(int x, int y){
x = find(x); y = find(y);
if(x != y) f[x] = y;
}
void work()
{
cin >> n >> m;
for(int i = 1; i <= n; ++i) f[i] = i;
for(int i = 1; i <= m; ++i)
{
cin >> x[i] >> y[i];
merge(x[i], y[i]);
}
for(int i = 1; i <= n; ++i) vcnt[find(i)]++;
for(int i = 1; i <= m; ++i) ecnt[find(x[i])]++;
ll ans = 1;
for(int i = 1; i <= n; ++i)
{
if(!vcnt[i]) continue;
if(vcnt[i] == ecnt[i])
ans = ans * 2 % mod;
else ans = 0;
}
cout << ans;
}
int main()
{
work();
return 0;
}
第四题 ABC236 E
题目解析
经典的平均数和中位数的处理
#include <bits/stdc++.h>
using namespace std;
template <class T> T maximize(const vector<T>& a) {
T s = 0, t = 0;
for (const T& x : a) {
const T u = max(s, t) + x;
s = t;
t = u;
}
return max(s, t);
}
int main() {
int n;
cin >> n;
vector<int> a(n);
for (int& x : a) {
cin >> x;
}
{
double ok = 1.0, ng = 1e9 + 1.0;
vector<double> b(n);
while ((ng - ok) / ng > 1e-3) {
const double md = sqrt(ok * ng);
for (int i = 0; i < n; ++i) {
b[i] = a[i] - md;
}
if (maximize(b) >= 0.0) {
ok = md;
} else {
ng = md;
}
}
cout << fixed << setprecision(12);
cout << ok << '\n';
}
{
int ok = 1, ng = 1000000000 + 1;
vector<int> b(n);
while (ng - ok > 1) {
const int md = (ok + ng) / 2;
for (int i = 0; i < n; ++i) {
b[i] = a[i] >= md ? 1 : -1;
}
if (maximize(b) > 0) {
ok = md;
} else {
ng = md;
}
}
cout << ok << '\n';
}
return 0;
}