Codeforces Round 690 (Div. 3)
Codeforces Round 690 (Div. 3)
https://codeforces.com/contest/1462
A. Favorite Sequence
按题意输出
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int a[N], n;
void solve () {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i < n / 2; i++) {
cout << a[i + 1] << ' ';
if (i + 1 != n - i) cout << a[n - i] << ' ';
}
if (n & 1) cout << a[n / 2 + 1];
cout << endl;
}
int main () {
int t;
cin >> t;
while (t--) solve ();
}
B. Last Year's Substring
形如:
...2020
2...020
20...20
202...0
2020...
分类讨论即可
#include <bits/stdc++.h>
using namespace std;
void solve () {
int n;
string s;
cin >> n >> s;
if (s[0] == '2' && s[n-3] == '0' && s[n-2] == '2' && s[n-1] == '0') cout << "YES\n";
else if (s[0] == '2' && s[1] == '0' && s[n-2] == '2' && s[n-1] == '0') cout << "YES\n";
else if (s[0] == '2' && s[1] == '0' && s[2] == '2' && s[n-1] == '0') cout << "YES\n";
else if (s[n-4] == '2' && s[n-3] == '0' && s[n-2] == '2' && s[n-1] == '0') cout << "YES\n";
else if (s[0] == '2' && s[1] == '0' && s[2] == '2' && s[3] == '0') cout << "YES\n";
else cout << "NO\n";
}
int main () {
int t;
cin >> t;
while (t--) solve ();
}
C. Unique Number
构造形如 123456789
易发现最达能构造出来的数字就是45,模拟即可,倒着从9开始填
#include <bits/stdc++.h>
using namespace std;
void solve () {
int n;
cin >> n;
//cout << n << ": ";
if (n < 10) cout << n << endl;
else if (n > 45) cout << "-1\n";
else {
vector<int> v;
for (int i = 9; i > 0; i--) {
int t = min (i, n);
//cout << t << ' ';
if (v.size () && v.back () == t) v.push_back (t - 1), v.push_back (1);
else v.push_back (t);
n -= t;
if (n == 0) break;
}
reverse (v.begin (), v.end ());
for (auto i : v) cout << i;
cout << endl;
}
}
int main () {
int t;
cin >> t;
while (t--) solve ();
}
D. Add to Neighbour and Remove
和固定,直接枚举最终局面,贪心计算和判断是否合法。
#include <bits/stdc++.h>
using namespace std;
const int N = 3005;
int a[N], n;
void solve () {
int sum = 0;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i], sum += a[i];
for (int len = n; len >= 1; len--) {
//剩下len个数
if (sum % len) continue;
int tt = sum / len, cur = 0, cnt = 0;
bool suc = true;
for (int i = 1; i <= n; i++) {
cur += a[i];
if (cur == tt) cnt++, cur = 0;
else if (cur > tt) {
suc = false;
break;
}
}
if (suc) {
cout << n - len << endl;
break;
}
}
}
int main () {
int t;
cin >> t;
while (t--) solve ();
}
E1. Close Tuples (easy version)
见下表:
x x+1 x+2
3 0 0
2 1 0
2 0 1
1 2 0
1 0 2
1 1 1
枚举然后计算次数即可
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5;
ll n, x, a[N];
void solve () {
ll ans = 0;
cin >> n;
for (int i = 1; i <= n + 3; i++) a[i] = 0;
for (int i = 1; i <= n; i++) cin >> x, a[x]++;
for (int i = 1; i <= n; i++) {
ll t = a[i], tt = a[i + 1], ttt = a[i + 2];
if (t >= 3) ans += (t * (t - 1) * (t - 2)) / 6;
if (tt > 0) ans += (t * (t - 1) / 2) * tt;
if (tt > 1) ans += t * (tt * (tt - 1) / 2);
if (ttt > 0) ans += t * tt * ttt + (t * (t - 1) / 2) * ttt;
if (ttt > 1) ans += t * (ttt * (ttt - 1) / 2);
}
cout << ans << endl;
}
int main () {
int t;
cin >> t;
while (t--) solve ();
}
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5;
ll n, x, a[N];
void solve () {
ll ans = 0;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort (a + 1, a + n + 1);
for (int i = 1; i <= n; i++) {
int pos = upper_bound (a + 1, a + n + 1, a[i] + 2) - a;
if (pos - i >= 3) {
ll len = pos - i - 1;
ans += len * (len - 1) / 2;
}
}
cout << ans << endl;
}
int main () {
int t;
cin >> t;
while (t--) solve ();
}
E2. Close Tuples (hard version)
相当于在 \([a_i, a_i+k]\) 范围的若干个数中选 \(m\) 个数的组合。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5, mod = 1e9 + 7;
ll n, m, k, a[N];
ll fact[N], infact[N];
ll qmi(ll a, ll k, ll p){
ll res = 1;
while(k){
if(k & 1)
res = (ll)res * a % p;
a = (ll)a * a % p;
k >>= 1;
}
return res;
}
ll C (int a, int b) {
if (a < b) return 0;
return fact[a] * infact[b] % mod * infact[a - b] % mod;
}
void init () {
fact[0] = infact[0] = 1;
for(int i = 1; i < N; i++){
fact[i] = (ll)fact[i-1] * i % mod;
infact[i] = (ll)infact[i-1] * qmi(i, mod - 2,mod) % mod;
}
}
void solve () {
ll ans = 0;
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) cin >> a[i];
sort (a + 1, a + n + 1);
for (int i = 1; i <= n; i++) {
int pos = upper_bound (a + 1, a + n + 1, a[i] + k) - a;
if (pos - i >= m) { //[ai, ai+k] 的范围内共 pos-i-1 个数中选
(ans += C (pos - i - 1, m - 1)) %= mod;
}
}
cout << ans << endl;
}
int main () {
init ();
int t;
cin >> t;
while (t--) solve ();
}
F. The Treasure of The Segments
计算每个区间的香蕉区间数,记录最大值。
具体计算:总区间数 - 相离区间数
相离:大于当前右端点的左端点数 + 大于当前左端点的右端点数
二分查找
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n;
struct Node {
int l, r;
bool operator<(const Node &t) const {
if (l != t.l) return l < t.l;
return r < t.r;
}
}p[N];
void solve () {
int ans = 1;
cin >> n;
vector<int> vl, vr;
for (int i = 1; i <= n; i++) {
cin >> p[i].l >> p[i].r;
vl.push_back (p[i].l);
vr.push_back (p[i].r);
}
sort (vl.begin (), vl.end ()), sort (vr.begin (), vr.end ());
for (int i = 1; i <= n; i++) {
int cnt = 1, l = p[i].l, r = p[i].r;
//找不相交的有多少个
int rr = upper_bound (vl.begin (), vl.end (), r) - vl.begin (); //在右侧不相交
rr = n - rr;
int ll = lower_bound (vr.begin (), vr.end (), l) - vr.begin (); //再左侧不相交
cnt = n - ll - rr;
ans = max (ans, cnt);
}
cout << n - ans << endl;
}
int main () {
int t;
cin >> t;
while (t--) solve ();
}