Codeforces Round 946 (Div. 3) 题解
Codeforces Round 946 (Div. 3) 题解
A. Phone Desktop 贪心
优先考虑放
#include<bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define pb push_back
#define all(u) u.begin(), u.end()
#define endl '\n'
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10, M = 105;
const int mod = 1e9 + 7;
const int cases = 1;
void Showball() {
int x, y;
cin >> x >> y;
int t = y / 2;
x -= t * 7;
if (y & 1) x -= 11, t++;
cout << t + (max(0, x) + 14) / 15 << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T = 1;
if (cases) cin >> T;
while (T--)
Showball();
return 0;
}
B. Symmetric Encoding 模拟
解密和加密过程一样,直接模拟即可。
void Showball() {
string s;
cin >> s >> s;
set<char> st;
for (auto c : s) st.insert(c);
string t = "";
for (auto c : st) t += c;
int n = t.size();
map<char, char> mp;
for (int i = 0; i < n; i++) {
mp[t[i]] = t[n - i - 1];
}
for (auto c : s) cout << mp[c];
cout << endl;
}
C. Beautiful Triple Pairs 计数
题意: 找出所有满足有一个位置上完全不同,其余两个位置相同的三元组对数。
思路: 根据不同元素的位置,可以分成三种情况,为了避免重复,我们可以维护出两个数组。
那么我们统计第一位不同的情况的答案时,就可以枚举所有的三元组, 每个三元组的贡献就为
其余两种情况同理。这两个数组用
最后答案记得除以
代码:
void Showball(){
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++) cin>>a[i];
map<array<int,3>,int> mp,mp2,mp3;
map<PII,int> s,s2,s3;
for(int i=0;i<n-2;i++){
mp[{a[i+1],a[i+2],a[i]}]++;
mp2[{a[i],a[i+2],a[i+1]}]++;
mp3[{a[i],a[i+1],a[i+2]}]++;
s[{a[i+1],a[i+2]}]++;
s2[{a[i],a[i+2]}]++;
s3[{a[i],a[i+1]}]++;
}
LL res=0;
for(auto [k,v]:mp) res+=v*(s[{k[0],k[1]}]-v);
for(auto [k,v]:mp2) res+=v*(s2[{k[0],k[1]}]-v);
for(auto [k,v]:mp3) res+=v*(s3[{k[0],k[1]}]-v);
cout<<res/2<<endl;
}
D. Ingenuity-2 思维
题意:给你方向指令,初始两人在同一点,请你分配两人去按照指令行走,每人必须至少走一步。使得两人走完指令后最终到达同一点。
思路:由于初始两人在同一点,那么我们想要保证两人最终在同一点,首先,相反方向可以让一个人走,就可以相互抵消,对于没有抵消的部分,如果是偶数次,那么就可以两人一起走,反之,则无解。所以直接判断相反方向的奇偶性是否相同即可。
注意一些特判,n=2时,必须两条指令相同,因为每人至少走一步。对于 n=4,并且每个方向走出现一次的情况。我们也需要分别让每个人走一对相反的方向即可。
代码:
void Showball() {
int n;
cin >> n;
string s;
cin >> s;
map<char, int> mp;
for (auto c : s) mp[c]++;
if (n == 2 && s[0] != s[1]) return cout << "NO\n", void();
if (n == 4 && mp['N'] && mp['S'] && mp['E'] && mp['W']) {
for (auto c : s) {
if (c == 'N' || c == 'S') cout << "R";
else cout << "H";
}
cout << endl;
return;
}
if ((mp['N'] & 1) != (mp['S'] & 1) || (mp['E'] & 1) != (mp['W'] & 1)) return cout << "NO\n", void();
map<char, int> mp2;
for (auto c : s) {
mp2[c]++;
if (mp2[c] == mp[c]) {
cout << (mp2[c] & 1 ? "R" : "H");
} else {
cout << (mp2[c] & 1 ? "R" : "H");
}
}
cout << endl;
}
E. Money Buys Happiness 思维 DP
题意:给你
注意:
思路:直接贪心显然是不对的,考虑DP,我们可以求出获得
代码:
void Showball() {
LL m, x;
cin >> m >> x;
vector<LL> c(m + 1), h(m + 1);
int sum = 0;
for (int i = 1; i <= m; i++) cin >> c[i] >> h[i], sum += h[i];
vector<LL> f(sum + 1, 1e18);
f[0] = 0;
for (int i = 1; i <= m; i++) {
for (int j = sum; j >= h[i]; j--) {
if (f[j - h[i]] + c[i] <= (i - 1)*x)
f[j] = min(f[j], f[j - h[i]] + c[i]);
}
}
for (int i = sum; i >= 0; i--) {
if (f[i] <= (m - 1)*x) {
return cout << i << endl, void();
}
}
}
F. Cutting Game 思维
题意:Alice 和 Bob 玩游戏,有一个大小为
每次操作后,该选手就会获得删除部分存在的所有筹码数量的得分。
求出操作结束后,两名选手各自的分数。
思路:因为删除的行或者列会永远消失,那么我们可以维护好剩余矩形的边界
注意到矩阵的范围很大,但是每个点比较离散,那么可以把所有的点存进一个队列,并且维护好每一行内部的顺序,这样需要
小tips:因为我们需要存每一行,每一列都有哪些点。如果开二维数组的话无疑会爆。所以我们可以开一个
代码:
void Showball() {
int a, b, n, m;
cin >> a >> b >> n >> m;
map<int, vector<int>> row, col;
for (int i = 1; i <= n; i++) {
int x, y;
cin >> x >> y;
row[x].pb(y);
col[y].pb(x);
}
deque<int> rows, cols;
int rl = 1, rr = a, cl = 1, cr = b;
for (auto &p : row) {
rows.pb(p.ff);
sort(all(p.ss));
}
for (auto &p : col) {
cols.pb(p.ff);
sort(all(p.ss));
}
auto calc = [&](vector<int> vec, int l, int r) {
int ret = 0;
if (l > r) return ret;
auto L = lower_bound(all(vec), l);
auto R = upper_bound(all(vec), r);
ret = R - L;
return ret;
};
int Alice = 0, Bob = 0;
for (int i = 0; i < m; i++) {
char op;
int k;
cin >> op >> k;
int cur = 0;
if (op == 'U') {
while (!rows.empty() && rows.front() < rl + k) {
int x = rows.front(); rows.pop_front();
cur += calc(row[x], cl, cr);
}
rl += k;
} else if (op == 'D') {
while (!rows.empty() && rows.back() > rr - k) {
int x = rows.back(); rows.pop_back();
cur += calc(row[x], cl, cr);
}
rr -= k;
} else if (op == 'L') {
while (!cols.empty() && cols.front() < cl + k) {
int x = cols.front(); cols.pop_front();
cur += calc(col[x], rl, rr);
}
cl += k;
} else {
while (!cols.empty() && cols.back() > cr - k) {
int x = cols.back(); cols.pop_back();
cur += calc(col[x], rl, rr);
}
cr -= k;
}
if (i & 1) Bob += cur;
else Alice += cur;
}
cout << Alice << " " << Bob << endl;
}
G. Money Buys Less Happiness Now 反悔贪心
题意:给你
注意:
思路:相比
代码:
void Showball(){
int m, x;
cin >> m >> x;
vector<int> c(m);
for (int i = 0; i < m; i++) {
cin >> c[i];
}
int sum = 0;
priority_queue<int> pq;
for (int i = 0; i < m; i++) {
sum -= c[i];
pq.push(c[i]);
if (sum < 0) sum += pq.top(), pq.pop();
sum += x;
}
cout<< pq.size() << endl;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [翻译] 为什么 Tracebit 用 C# 开发
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· 刚刚!百度搜索“换脑”引爆AI圈,正式接入DeepSeek R1满血版