Educational Codeforces Round 161 (Rated for Div. 2)(A-E)
Educational Codeforces Round 161 (Rated for Div. 2)(A-E)
A Tricky Template
分析
样例给的很强,读完做法就出来了。思考一下就是,如果有一个位置c[i]与a[i]和b[i]均不同,那么在此位置上就可以使用一个大写字母使得与c不匹配,而不会影响a和b,如果没有这样的位置,也就是说不管如何c[i]都会和前两个有一个重复,那么模板对应位置不管怎么放,都会对其中两个串产生相同的影响,因此与题目给定的要求是互斥的
代码
点击查看代码
void solve () {
int n; cin >> n;
string a, b, c; cin >> a >> b >> c;
bool fl = false;
for (int i = 0; i < n; i ++) {
if (a[i] != c[i] && b[i] != c[i]) fl = true;
}
if (fl) cout << "YES" << endl;
else cout << "NO" << endl;
return ;
}
B Forming Triangles
分析
因为边长都是2的幂次,我们知道\(2^{i - 1} + 2^{i - 1} = 2^{i}\),而三角形两边之和大于第三边,因此最长边起码有两条
代码
点击查看代码
ll calc1(ll x) {
return x * (x - 1) / 2;
}
ll calc2(ll x) {
return x * (x - 1) * (x - 2) / 6;
}
void solve () {
int n; cin >> n;
vector<int> a(n + 1);
map<ll, int> mp;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
mp[a[i]] ++;
}
ll ans = 0, cn = 0;
for (int i = 0; i <= n; i ++) {
ans += calc1(mp[i]) * cn + calc2(mp[i]);
cn += mp[i];
}
cout << ans << endl;
return ;
}
C Closest Cities
分析
每次都是一定走到相邻的城市,前后缀和维护一下即可
代码
点击查看代码
void solve () {
int n; cin >> n;
vector<ll> a(n + 2);
for (int i = 1; i <= n; i ++) cin >> a[i];
a[0] = -INF;
a[n + 1] = -a[0];
vector<ll> pre(n + 2), suf(n + 2);
for (int i = 1; i <= n; i ++) {
if (a[i] - a[i - 1] < a[i + 1] - a[i]) pre[i + 1] = pre[i] + a[i + 1] - a[i];
else pre[i + 1] = pre[i] + 1;
}
for (int i = n; i >= 1; i --) {
if (a[i] - a[i - 1] < a[i + 1] - a[i]) suf[i - 1] = suf[i] + 1;
else suf[i - 1] = suf[i] + a[i] - a[i - 1];
}
int m; cin >> m;
while (m --) {
int x, y; cin >> x >> y;
if (x < y) cout << pre[y] - pre[x] << endl;
else cout << suf[y] - suf[x] << endl;
}
return ;
}
D Berserk Monsters
分析
模拟即可
代码
点击查看代码
void solve () {
int n; cin >> n;
vector<int> a(n + 2), d(n + 2), l(n + 2), r(n + 2), alive;
vector<bool> ok(n + 2);
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i ++) cin >> d[i];
for (int i = 1; i <= n; i ++) l[i] = i - 1, r[i] = i + 1;
for (int i = 1; i <= n; i ++) alive.pb(i), ok[i] = true;
for (int i = 1; i <= n; i ++) {
set<int> death;
for (auto it : alive)
if (a[l[it]] + a[r[it]] > d[it])
death.insert(it);
alive.clear();
cout << death.size() << ' ';
for (auto it : death) ok[it] = false;
for (auto it : death) {
r[l[it]] = r[it];
l[r[it]] = l[it];
if (l[it] != 0 && ok[l[it]]) alive.pb(l[it]);
if (r[it] != n + 1 && ok[r[it]]) alive.pb(r[it]);
}
}
cout << endl;
return ;
}
E Increasing Subsequences
分析
易知长度为i的递增序列包含的递增子序列个数为\(2 ^ {i}\),那么对于要求的x,我们首先从零开始放置,如0,1,2,3···直到这段递增序列包含的递增子序列数量刚好对应x二进制拆位中最大的1,然后从最高位1减一的位置反过来放,如0,1,2,3,4,5,3,2这样,其中0,1,2,3,4,5表示x的二进制位中最高位1为第六位,此时产生的总数为\(2 ^ 6\),此时从x的次高位1反过来遍历,第i位是1就放,放置之后可产生\(2 ^ i\)的贡献,而不会与后续逆序放置的数产生影响
代码
点击查看代码
void solve () {
ll x; cin >> x;
vector<int> ans;
for (int i = 0; i < __lg(x); i ++)
ans.pb(i);
for (int i = __lg(x) - 1; i >= 0; i --) {
if (x >> i & 1)
ans.pb(i);
}
cout << ans.size() << endl;
for (auto a : ans)
cout << a << ' ';
cout << endl;
return ;
}

浙公网安备 33010602011771号