这次感觉比之前简单一些
A - Echo
题目
给一个字符串s
,重复每个字符两次
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i ++)
#define df(i, j, k) for (int i = j; i >= k; i --)
using namespace std;
void solve()
{
int n;
string s;
cin >> n >> s;
for (auto c : s) cout << c << c;
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
B - Base 2
题目
给一个01输入,二进制转十进制
#include <bits/stdc++.h>
#define int unsigned long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i ++)
#define df(i, j, k) for (int i = j; i >= k; i --)
using namespace std;
void solve()
{
int ans = 0;
uf (i, 0, 63)
{
int t;
cin >> t;
if (t) ans += 1ull << i;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
C - Centers
题目
给 3n 长的序列, 1~n 的元素会重复三次,按照出现在中间的元素位置升序输出每个元素
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i ++)
#define df(i, j, k) for (int i = j; i >= k; i --)
using namespace std;
const int N = 1e5 + 5;
int a[N * 3];
bool st[N];
void solve()
{
int n;
cin >> n;
unordered_map<int, int> mp;
uf (i, 1, 3 * n)
{
cin >> a[i];
if (st[a[i]])
{
mp[a[i]] = i;
st[a[i]] = 0;
}
else st[a[i]] = 1;
}
vector<pii> p (all(mp));
sort(all(p), [](pii a, pii b)
{
return a.y < b.y;
});
for (auto pair : p) cout << pair.x << " ";
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
D - Poisonous Full-Course
题目
由n种菜,每种菜有毒或者解毒,都有一个味道值;初始健康,吃一个有毒的菜会不舒服,如果连续吃两个有毒的菜就会die,如果吃了一个有毒的菜再吃一个解毒的菜就能恢复健康。对于每一种菜可以选择吃或者不吃,求吃下的菜最大的味道值。
- dp,两种状态,
dp[i][0 / 1]
:当前吃到第i
种菜且为0/1
状态的最大滋味值(0为健康,1为不舒服) - 状态转移看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i ++)
#define df(i, j, k) for (int i = j; i >= k; i --)
using namespace std;
const int N = 3e5 + 5;
vector<pii> a(N);
void solve()
{
int n;
cin >> n;
uf (i, 1, n) cin >> a[i].x >> a[i].y;
vector<vi> dp(N, vi(2, 0));
uf (i, 1, n)
{
if (a[i].x == 1) //有毒
{
dp[i][0] = dp[i - 1][0]; //跳过
dp[i][1] = max(dp[i - 1][0] + a[i].y, dp[i - 1][1]); //在健康状态下可以吃,不舒服状态跳过
}
else
{
dp[i][0] = max({dp[i - 1][0], dp[i - 1][0] + a[i].y, dp[i - 1][1] + a[i].y}); //健康状态不吃、健康状态下吃、不舒服状态下吃
dp[i][1] = dp[i - 1][1]; //不舒服状态下选择不吃
}
}
cout << max(dp[n][0], dp[n][1]) << endl;
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
E - Best Performances
题目
初始全为0的序列,q次修改, 每次修改某个位置x
上的数为 y
, 然后输出最大的 k
个数的和
- 用两个堆来维护,
heap
维护 最大的k
个数,other
维护没有在heap
里面的数 - 当修改x位置上的数为y时就可以判断:
- x不在
heap
中:判断能不能加入heap
- x 在
heap
中:判断能不能继续在heap
中
- x不在
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define vi vector<int>
#define pii pair<int, int>
#define mset(x, v) memset(x, v, sizeof x)
#define all(x) ((x).begin()), ((x).end())
#define uf(i, j, k) for (int i = j; i <= k; i ++)
#define df(i, j, k) for (int i = j; i >= k; i --)
using namespace std;
const int N = 5e5 + 5;
int n, k, q;
vi a(N, 0);
void solve()
{
cin >> n >> k >> q;
set<pii> heap, other;
unordered_set<int> st;
int sum = 0;
uf (i, 1, k) heap.insert({0, i}), st.insert(i);
uf (i, k + 1, n) other.insert({0, i});
int x, y;
while (q --)
{
cin >> x >> y;
int pre = a[x];
a[x] = y;
auto mn = (*heap.begin()).x, pos = (*heap.begin()).y;
if (st.count(x)) //存在于堆中
{
int mx = INT_MIN, p = 0;
if (other.size()) mx = (*other.rbegin()).x, p = (*other.rbegin()).y;
if (y >= mx) //大于最小值没有影响
{
heap.erase({pre, x});
heap.insert({y, x});
sum = sum + y - pre;
}
else
{
other.erase({mx, p});
other.insert({y, x});
heap.insert({mx, p});
heap.erase({pre, x});
st.insert(p);
st.erase(x);
sum = sum - pre + mx;
}
}
else //不存在于堆中
{
if (y > mn) //只有大于堆的最小值才能加入
{
heap.erase(heap.begin());
heap.insert({y, x}); //插入到堆中
other.erase({pre, x}); //从其他删除
other.insert({mn, pos}); //插入到其他
st.erase(pos); //从堆里面删除
st.insert(x);
sum = sum + y - mn;
}
else
{
other.erase({pre, x});
other.insert({y, x});
}
}
cout << sum << endl;
}
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
自己和镜中对抗
赢不回诗和远方
任世故欲盖弥彰
他奋力撕掉伪装
转身间对视过往
道一句 怪人生无常