随笔 - 12  文章 - 0  评论 - 0  阅读 - 262

Codeforces 820 Div3

T1
题意:两个电梯,电梯1:直接从a楼前往1楼; 电梯2:从b楼到c楼再到1楼,问那个电梯时间更短

直接模拟即可

点击查看代码
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--){
int a, b, c; std::cin >> a >> b >> c;
int x = a - 1, y = std::abs(b - c) + c - 1;
std::cout << (x < y ? 1 : x == y ? 3 : 2 )<< '\n';
}
return 0;
}

T2
将一个数字字符串解码为英文字符串,加密规则:若字母<10,直接转换为该数字,>0转换为数字后加个0

对应解码:从后往前遍历,若遇到零,则取前两位数字转换为对应字母,若不为0,则直接转换为对应字母

点击查看代码
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--){
int n; std::cin >> n;
std::string s; std::cin >> s;
std::vector<char> in;
for(int i = n - 1; i >= 0; --i){
if(s[i] == '0'){
int x = (s[i - 2] ^ 48) * 10 + (s[i - 1] ^ 48);
in.push_back(x - 1 + 'a');
i -= 2;
}else{
in.push_back((s[i] ^ 48) - 1 + 'a');
}
}
std::reverse(in.begin(), in.end());
for(auto x : in){
std::cout << x;
} std::cout << '\n';
}
return 0;
}

T3
给定一个字符串,从开头走至结尾,每个位置只能走一次,跳跃代价为字母差的绝对值,求最小代价,同时在最小代价的前提下,取最大步数。

取26个桶记录每个字母数量,则从开头字母到末尾字母的最小代价记为开头桶到结尾同的有值解,最大步数记为这些桶的个数和

点击查看代码
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--){
std::string s; std::cin >> s;
char a = s[0], b = s.back();
std::vector<int> v(26);
std::vector<int> op[26];
for(int i = 0; i < (int)s.size(); ++i){
v[s[i] - 'a']++;
op[s[i] - 'a'].push_back(i + 1);
}
int ans = 0, step = 0;
char pre = '-'; std::vector<int> lx;
for(char x = a; a <= b ? x <= b : x >= b; a <= b ? ++x : --x){
if(v[x - 'a']){
step += v[x - 'a'];
if(pre == '-'){
pre = x;
}else{
ans += std::abs((int)(x - pre));
pre = x;
}
for(auto xx : op[x - 'a']){
lx.push_back(xx);
}
}
}
std::cout << ans << ' ' << step << '\n';
for(auto x : lx){
std::cout << x << ' ';
} std::cout << '\n';
}
return 0;
}

T4

共n人,每人消费xi, 有yi元,至少两人组队,且队内总钱数必须大于等于总消费,问最多可以组成多少个队?

处理出每个人盈余后排序,尽可能让盈余正的与最能与其组队的负盈余组队,若还有正盈余的再两两组队

点击查看代码
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--){
int n; std::cin >> n;
std::vector<int> x(n), y(n);
for(int i = 0; i < n; ++i){
std::cin >> x[i];
}
for(int j = 0; j < n; ++j){
std::cin >> y[j];
}
std::vector<int> z(n); int p = n;
for(int i = 0; i < n; ++i){
z[i] = y[i] - x[i];
}
std::sort(z.begin(), z.end());
for(int i = 0; i < n; ++i){
if(z[i] >= 0 && p == n){
p = i;
}
}
int ans = 0;
for(int i = 0, j = n - 1; i < p; ++i){
if(j >= p && z[i] + z[j] >= 0){
--j;
++ans;
}
}
ans += (n - p - ans) / 2;
std::cout << ans << '\n';
}
return 0;
}

T5
交互题:有n个点形成一个圆,最多50次交互,求n
交互规则:?a b 得到a b之间有多少条边
若a <= n && b <= n (1 / 2概率获取其中一个边数)
否则得到-1

从前往后顺序交互?1 : i 和 ? i : 1
如果都为-1则得到 i- 1
如果x != y 得到x + y
50次得概率(0.5)^ (50)很小

点击查看代码
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
i64 x, y;
for(int i = 4; i <= 30; ++i){
std::cout << "? " << 1 << ' ' << i << std::endl;
std::cin >> x;
std::cout << "? " << i << ' ' << 1 << std::endl;
std::cin >> y;
if(x == -1 && y == -1){
std::cout << "! " << i - 1 << std::endl;
return 0;
}
if(x != y){
std::cout << "! " << x + y << std::endl;
return 0;
}
}
return 0;
}

T6

求最小的L1, L2使得v(L1, L1 + w - 1) * v(l, r) + v(L2, L2 + w - 1)与k模9同余

处理出长度为w最早的余9为i的L进行处理即可

点击查看代码
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--){
std::string s; std::cin >> s;
int n = (int)s.size();
std::vector<int> a(n);
for(int i = 0; i < n; ++i){
a[i] = (s[i] ^ 48) % 9;
}
std::vector<int> pre(n); pre[0] = a[0];
for(int i = 1; i < n; ++i){
pre[i] = (pre[i - 1] + a[i]) % 9;
}
int w, m; std::cin >> w >> m;
std::vector<std::vector<int>> check(9);
for(int i = 0; i + w - 1 < n; ++i){
int j = i + w - 1;
int now = ((pre[j] - (i == 0 ? 0 : pre[i - 1])) % 9 + 9) % 9;
check[now].push_back(i + 1);
}
for(int i = 0; i < m; ++i){
int l, r, k; std::cin >> l >> r >> k; --l, --r;
int x = ((pre[r] - (l == 0 ? 0 : pre[l - 1])) % 9 + 9) % 9;
int l1 = -1, l2 = -1, key = 0;
for(int ii = 0; ii < 9; ++ii){
for(int jj = 0; jj < 9; ++jj){
if(check[ii].empty() || check[jj].empty() || (ii * x + jj) % 9 != k){
continue;
}
if(ii == jj && check[ii].size() == 1){
continue;
}
if(l1 == -1 || (check[ii][0] < l1) || (check[ii][0] == l1 && check[jj][0] < l2)){
l1 = check[ii][0];
l2 = ii == jj ? check[jj][1] : check[jj][0];
}
}
}
std::cout << l1 << ' ' << l2 << '\n';
}
}
return 0;
}

T7

给定s,t,破坏s中出现的某些t,使得s中再没有t子串,求最小破坏数,同时在最小破坏数的前提下求有多少种方案数?

考虑dp,见代码

点击查看代码
#include<bits/stdc++.h>
using i64 = long long;
constexpr int P = (int)1e9 + 7;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--){
std::string a, b; std::cin >> a >> b;
int n = a.size(), m = b.size();
std::vector<int> c(n); int p = -1;
for(int i = 0; i + m - 1 < n; ++i){
if(a.substr(i, m) == b){
c[i] = 1;
p = i;
}
}
std::vector<std::pair<int, int>> dp(n + 1, {n + 1, 0});
dp[0] = {0, 1};
for(int i = 0; i < n; ++i){
for(int j = i; j + m <= n; ++j){
if(j - i >= m && c[j - m]){
break;
}
if(c[j]){
if(dp[i].first + 1 < dp[j + m].first){
dp[j + m] = dp[i];
dp[j + m].first = (dp[i].first + 1) % P;
}else if(dp[i].first + 1 == dp[j + m].first){
dp[j + m].second = (dp[i].second + dp[j + m].second) % P;
}
}
}
}
std::pair<int, int> ans{n + 1, 0};
for(int i = p + 1; i <= n; ++i){
if(dp[i].first == ans.first){
ans.second = (ans.second + dp[i].second) % P;
}else if(dp[i].first < ans.first){
ans = dp[i];
}
}
std::cout << ans.first << ' ' << ans.second << '\n';
}
return 0;
}
posted on   航海士  阅读(13)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示