天梯赛训练
天梯赛训练
A - A 洛谷 - P2669
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
i64 n = 0, ans = 0;
cin >> n;
i64 i = 1, t = 0;
while (t < n) {
ans += i * min(i, n - t);
t += i;
i ++;
}
cout << ans << '\n';
return 0;
}
B - B 洛谷 - P5660
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int num = 0;
string s;
cin >> s;
for(auto i : s)
num += (i == '1');
cout << num << '\n';
return 0;
}
C - C 洛谷 - P5015
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
getline(cin, s);
int num = s.size();
for (auto i : s)
num -= (i == ' ');
cout << num << '\n';
return 0;
}
D - D 洛谷 - P5681
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
i64 a,b,c;
cin >> a >> b >> c;
if(a * a > b * c) cout << "Alice\n";
else cout << "Bob\n";
return 0;
}
E - E 洛谷 - P1190
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<int> w(n);
int mx = 0, sum = 0;
for (auto &i : w) {
cin >> i;
mx = max(mx, i);
sum += i;
}
if (n <= m) {
cout << mx << '\n';
} else {
vector<int> d(m);
for (int i = 0; i < n; i ++) {
int now = INT_MAX, loc = -1;
for (int j = 0; j < m; j ++) {
if (d[j] < now) {
now = d[j], loc = j;
}
}
d[loc] += w[i];
}
int ans = 0;
for (int i = 0; i < m; i ++)
ans = max(ans, d[i]);
cout << ans << '\n';
}
return 0;
}
F - F 洛谷 - P7071
按照其二进制对应输出\(2^k\)即可
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
if (n & 1) {
cout << "-1\n";
} else {
for (int i = 30; i >= 0; i --) {
if (n >= (1 << i)) {
cout << (1 << i) << ' ';
n -= (1 << i);
}
}
}
return 0;
}
G - G 洛谷 - P2670
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<string> s(n);
for (auto &i : s) cin >> i;
int u[] = {1,1,1,-1,-1,-1,0,0},v[] = {1,0,-1,1,0,-1,1,-1};
vector ans(n, vector<int>(m));
for (int i = 0; i < n; i ++) {
for (int j = 0; j < m; j ++) {
if (s[i][j] == '*') {
for (int k = 0; k < 8; k ++) {
int x = i + u[k];
int y = j + v[k];
if (x >= 0 && x < n && y >= 0 && y < m)
ans[x][y] ++;
}
}
}
}
for (int i = 0; i < n; i ++) {
for (int j = 0; j < m; j ++)
if (s[i][j] == '*') cout << s[i][j];
else cout << ans[i][j];
cout << '\n';
}
return 0;
}
H - H 洛谷 - P1098
模拟;
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int p1, p2, p3;
string s;
cin >> p1 >> p2 >> p3 >> s;
string ans = "";
ans += s[0];
for (int i = 1; i < s.size() - 1; i ++) {
if (s[i] == '-' && s[i + 1] > s[i - 1]) {
if (s[i - 1] + 1 == s[i + 1]) continue;
string str = "";
char st, ed;
st = s[i - 1] + 1, ed = s[i + 1] - 1;
if (s[i - 1] >= '0' && s[i + 1] <= '9') {
for (char j = st; j <= ed; j ++)
str += string(p2, j);
} else if (s[i - 1] >= 'a' && s[i + 1] <= 'z') {
if (p1 == 2) st -= 32, ed -= 32;
for (char j = st; j <= ed; j ++)
str += string(p2, j);
} else {
ans += s[i];
continue;
}
if (p1 == 3) str = string(str.size(), '*');
if (p3 == 2) reverse(str.begin(), str.end());
ans += str;
} else {
ans += s[i];
}
}
ans += s.back();
cout << ans;
return 0;
}
I - I 洛谷 - P5657
手玩几个例子后找到规律;
以\(n=4,k=13\)为例,\(k\)大于\(2^3\),说明它是由\(n=3\)的格雷码在前面加\(1\)得到的,否则就是在前面加\(0 \dots\)
上述答案为1011,即\(1+011\rightarrow 10 + 11\rightarrow 101+1\),以\(0\sim 2^k - 1\)标号则位置转移关系为\(13 \rightarrow 2 \rightarrow 2 \rightarrow 1\)即\(13 \rightarrow (15 - 13) \rightarrow 2 \rightarrow (3 - 2)\)即\(13 \rightarrow (2^4-1)-13 \rightarrow 2 \rightarrow (2^2-1)-2\);
即当前位置超过\(2^{k-1}\)时,都应该转换到\(2^k-1-x\)的位置,否则就按照原来的位置;
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
i64 n, k;
cin >> n >> k;
string ans = "";
auto dfs = [&](auto dfs, i64 x, i64 now)->void{
if (!now) {
cout << ans << '\n';
exit(0);
}
if (x >= (1ll << (now - 1))) {
ans += '1';
dfs(dfs, (1ll << now) - 1 - x, now - 1);
} else{
ans += '0';
dfs(dfs, x, now - 1);
}
};
dfs(dfs, k, n);
return 0;
}
J - J 洛谷 - P1309
应该是归并排序的典题了,快排回超时,得用归并排序可以手写也可以直接用\(merge\)函数;
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, r, q;
cin >> n >> r >> q;
n *= 2, q--;
vector<array<int, 3>> ans(n), winner(n/2), loser(n/2);
for (int i = 0; i < n; i ++)
cin >> ans[i][0], ans[i][1] = i + 1;
for (int i = 0; i < n; i ++)
cin >> ans[i][2];
auto cmp = [&](array<int, 3> &a, array<int, 3> &b) -> bool{
if (a[0] == b[0]) return a[1] < b[1];
return a[0] > b[0];
};
sort(ans.begin(), ans.end(), cmp);
while (r --) {
for (int i = 0; i < n; i += 2) {
if (ans[i][2] > ans[i + 1][2]) {
ans[i][0] ++;
winner[i / 2] = ans[i];
loser[i / 2] = ans[i + 1];
} else {
ans[i + 1][0] ++;
winner[i / 2] = ans[i + 1];
loser[i / 2] = ans[i];
}
}
merge(winner.begin(),winner.end(),loser.begin(),loser.end(),ans.begin(),cmp);
}
cout << ans[q][1] << '\n';
return 0;
}
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, r, q;
cin >> n >> r >> q;
n *= 2, q--;
vector<array<int, 3>> ans(n), winner(n), loser(n);
for (int i = 0; i < n; i ++)
cin >> ans[i][0], ans[i][1] = i + 1;
for (int i = 0; i < n; i ++)
cin >> ans[i][2];
auto cmp = [&](array<int, 3> &a, array<int, 3> &b) -> bool{
if (a[0] == b[0]) return a[1] < b[1];
return a[0] > b[0];
};
sort(ans.begin(), ans.end(), cmp);
while (r --) {
for (int i = 0; i < n; i += 2) {
if (ans[i][2] > ans[i + 1][2]) {
ans[i][0] ++;
winner[i / 2] = ans[i];
loser[i / 2] = ans[i + 1];
} else {
ans[i + 1][0] ++;
winner[i / 2] = ans[i + 1];
loser[i / 2] = ans[i];
}
}
int m = n / 2;
int cnta = 0, cntw = 0, cntl = 0;
while (cntw < m && cntl < m) {
if (cmp(winner[cntw], loser[cntl])) ans[cnta ++] = winner[cntw ++];
else ans[cnta ++] = loser[cntl ++];
}
while (cntw < m) ans[cnta ++] = winner[cntw ++];
while (cntl < m) ans[cnta ++] = loser[cntl ++];
}
cout << ans[q][1] << '\n';
return 0;
}
K - K 洛谷 - P2058
题目保证时间递增,可以采用单调队列将不在一天的信息移出去;
维护每艘船的数量,当某艘船数量为0时从答案中移除;
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector k(n, vector<int>());
deque<int> time;
vector<int> num(100010), t(n);
set<int> ans;
for (int i = 0; i < n; i ++) {
int p;
cin >> t[i] >> p;
for (int j = 0; j < p; j ++) {
int x;
cin >> x;
k[i].push_back(x);
num[x] ++;
ans.insert(x);
}
time.push_back(i);
while (t[time.front()] <= t[i] - 86400) {
int io = time.front();
for (auto x : k[io]) {
if (!--num[x]) ans.erase(x);
}
time.pop_front();
}
cout << ans.size() << '\n';
}
return 0;
}
N - N 洛谷 - P2048
贪心+堆+RMQ;
每段超级和弦都是这段区间里的和,而区间和不难想到前缀和,如果考虑暴力,那么需要将所有满足条件的区间抽出来排序,但是在\(n\)过大时这是难以想象的;
那么对于一个区间,其贡献就是其子区间中和最大的区间,要求出这个最大和,那就是RMQ的问题了,这里可以用ST表求出区间最大的和的下标值,当然一个区间中也有可能有多个区间满足第二大,第三大等等,所以每次取出最大和的区间后应该把区间向两边缩减,例如[1,10]这个区间的最大和的下标在5,但是[1,4]或者[6,10]也可能产生次最大和,所以我们也要考虑进去;
进行贪心的话,可以考虑用一个优先队列放置区间,排序规则就按区间最大和排序;
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
const int N = 5e5 + 10;
i64 sum[N], Cnt[N][20];
void init(int n) {
for (int i = 1; i <= n; i ++)
Cnt[i][0] = i;
for (int j = 1; (1 << j) <= n; j ++) {
for (int i = 1; i + (1 << j) - 1 <= n; i ++) {
int x = Cnt[i][j - 1], y = Cnt[i + (1 << (j - 1))][j - 1];
Cnt[i][j] = sum[x] > sum[y] ? x : y;
}
}
}
int query(int l, int r) {
if (r < l) return INT_MIN;
int k = log2(r - l + 1);
int x = Cnt[l][k], y = Cnt[r - (1 << k) + 1][k];
return sum[x] > sum[y] ? x : y;
}
struct E {
int o, l, r, t;
E(int o, int l, int r) : o(o), l(l), r(r), t(query(l, r)) {}
friend bool operator < (const E& a, const E& b) {
return sum[a.t] - sum[a.o - 1] < sum[b.t] - sum[b.o - 1];
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, k, L, R;
cin >> n >> k >> L >> R;
priority_queue<E> Q;
for (int i = 1; i <= n; i ++) {
cin >> sum[i];
sum[i] += sum[i - 1];
}
init(n);
for (int i = 1; i <= n; i ++)
if (i + L - 1 <= n)
Q.push({i, i + L - 1, min(i + R - 1, n)});
i64 ans = 0;
while (k --) {
auto [o, l, r, t] = Q.top();
Q.pop();
ans += sum[t] - sum[o - 1];
if (l != t) Q.push({o, l, t - 1});
if (r != t) Q.push({o, t + 1, r});
}
cout << ans << '\n';
return 0;
}