一、前言
强度有点大,只写了三道题
二、题目总览
三、具体题目
只放前四道题,后面题目难度大,受众小
3.1 A. King Keykhosrow's Mystery
思路
要透过题目看本质,实际上就是需要我们求两个数的lcm即最小公倍数
我的代码
// Problem: A. King Keykhosrow's Mystery
// Contest: Codeforces - Rayan Programming Contest 2024 - Selection (Codeforces Round 989, Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/2034/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using pii = std::pair<int,int>;
constexpr int N = 1e5+5,M = 1e6+5,INF = 0x3f3f3f3f;
#define pb emplace_back
#define all(v) v.begin(),v.end()
int lcm(int a,int b){
return a/std::__gcd(a,b)*b;
}
void solve(){
int a,b;std::cin >> a >> b;
std::cout << lcm(a,b) << '\n';
}
int main(){
std::cin.tie(nullptr)->sync_with_stdio(false);
int tt = 1;
std::cin >> tt;
for(int ti = 0;ti<tt;++ti){
solve();
}
return 0;
}
3.2 B. Rakhsh's Revival
思路
贪心的思路,如果遇到了连续的m个'0',那么就从第m个'0'开始替换掉后k个字符为连续的'1',最后的操作数就是答案,注意用string.find()函数时,最好用string.find(str,pos)的重载版本,不然会超时,因为只有一个参数的时候,默认是从字符串的开头开始找的,当k很小但n很大时会TLE
我的代码
// Problem: B. Rakhsh's Revival
// Contest: Codeforces - Rayan Programming Contest 2024 - Selection (Codeforces Round 989, Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/2034/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using pii = std::pair<int,int>;
constexpr int N = 1e5+5,M = 1e6+5,INF = 0x3f3f3f3f;
#define pb emplace_back
#define all(v) v.begin(),v.end()
void solve(){
i64 n,m,k;std::cin >> n >> m >> k;
std::string s;std::cin >> s;
std::string target;
std::string rep;
for(int i = 0;i<m;++i){
target+='0';
// rep+='1';
}
for(int i = 0;i<k;++i){
rep+='1';
}
int ans = 0;
int pos = 0;
while((pos=s.find(target,pos))!=std::string::npos){
s.replace(pos+m-1,k,rep);
++ans;
}
std::cout << ans << '\n';
}
int main(){
std::cin.tie(nullptr)->sync_with_stdio(false);
int tt = 1;
std::cin >> tt;
for(int ti = 0;ti<tt;++ti){
solve();
}
return 0;
}
3.3 C. Trapped in the Witch's Labyrinth
思路
我们发现,从最外层开始判断,如果第一行的字符是'U',那么都是可以逃脱的,如果最后一行的字符是'D',那么也是可以逃脱的,同理,第一列字符是'L',最后一列字符是'R'都是可以逃脱的,然后对这些点进行bfs,如果有指向这些点的点,也都是可以逃脱的,然后把这个点入队列。处理结束后,我们还需要判断'?',如果'?'四个方向都是可以逃脱的点,那么当前'?'也是可以逃脱的点,否则'?'就不是可以逃脱的点。大致就是这样的思路,具体实现见代码
我的代码
// Problem: C. Trapped in the Witch's Labyrinth
// Contest: Codeforces - Rayan Programming Contest 2024 - Selection (Codeforces Round 989, Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/2034/problem/C
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using pii = std::pair<int,int>;
constexpr int N = 1e3+5,M = 1e6+5,INF = 0x3f3f3f3f;
#define pb emplace_back
#define all(v) v.begin(),v.end()
char g[N][N];
bool vis[N][N];
int dx[] = {0,0,-1,1};
int dy[] = {-1,1,0,0};
int n,m;
using Node = std::array<int,2>;
void bfs(){
std::queue<Node> q;
for(int i = 1;i<=m;++i){
if(vis[1][i]){
q.push({1,i});
}
if(vis[n][i]){
q.push({n,i});
}
}
for(int i = 1;i<=n;++i){
if(vis[i][1]){
q.push({i,1});
}
if(vis[i][m]){
q.push({i,m});
}
}
/*int dx[] = {0,0,-1,1};
int dy[] = {-1,1,0,0};*/
while(!q.empty()){
auto t = q.front();
q.pop();
for(int i = 0;i<4;++i){
int u = t[0]+dx[i],v = t[1]+dy[i];
if(u<1||u>n||v<1||v>m) continue;
if(vis[u][v]) continue;
if(i==0&&g[u][v]=='R') {
vis[u][v] = true;
q.push({u,v});
}else if(i==1&&g[u][v]=='L') {
vis[u][v] = true;
q.push({u,v});
}else if(i==2&&g[u][v]=='D'){
vis[u][v] = true;
q.push({u,v});
}else if(i==3&&g[u][v]=='U'){
vis[u][v] = true;
q.push({u,v});
}
}
}
}
void solve(){
std::cin >> n >> m;
for(int i = 1;i<=n;++i){
for(int j = 1;j<=m;++j){
std::cin >> g[i][j];
}
}
for(int i = 1;i<=m;++i){
if(g[1][i]=='U'){
vis[1][i] = true;
}
if(g[n][i]=='D'){
vis[n][i] = true;
}
}
for(int i = 1;i<=n;++i){
if(g[i][1]=='L'){
vis[i][1] = true;
}
if(g[i][m]=='R'){
vis[i][m] = true;
}
}
bfs();
for(int i = 1;i<=n;++i){
for(int j = 1;j<=m;++j){
if(g[i][j]=='?'){
bool flag = false;
for(int k = 0;k<4;++k){
int u = i+dx[k],v = j+dy[k];
if(u<1||u>n||v<1||v>m) continue;
if(!vis[u][v]){
flag = true;
break;
}
}
if(!flag) vis[i][j] = true;
}
}
}
int ans = n*m;
for(int i = 1;i<=n;++i){
for(int j = 1;j<=m;++j){
if(vis[i][j]) --ans;
}
}
std::cout << ans << '\n';
//恢复
for(int i = 1;i<=n;++i){
for(int j = 1;j<=m;++j){
vis[i][j] = false;
}
}
}
int main(){
std::cin.tie(nullptr)->sync_with_stdio(false);
int tt = 1;
std::cin >> tt;
for(int ti = 0;ti<tt;++ti){
solve();
}
return 0;
}
3.4 D. Darius' Wisdom
思路
直接看jiang老师代码吧
jiangly的代码
#include <bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
auto get(std::vector<int> a) {
int n = a.size();
std::vector<std::array<int, 2>> ans;
std::set<int> s[3];
for (int i = 0; i < n; i++) {
s[a[i]].insert(i);
}
auto swap = [&](int i, int j) {
ans.push_back({i + 1, j + 1});
assert(std::abs(a[i] - a[j]) == 1);
s[a[i]].erase(i);
s[a[j]].erase(j);
std::swap(a[i], a[j]);
s[a[i]].insert(i);
s[a[j]].insert(j);
};
for (int i = 0; i < n; i++) {
if (s[1].empty()) {
// do nothing
} else if (s[0].empty()) {
if (a[i] == 2) {
swap(i, *s[1].begin());
}
} else {
if (a[i] == 2) {
swap(i, *s[1].begin());
}
if (a[i] == 1) {
swap(i, *s[0].begin());
}
}
s[a[i]].erase(i);
}
assert(std::is_sorted(a.begin(), a.end()));
return ans;
}
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
auto ans = get(a);
if (ans.size() > n) {
std::reverse(a.begin(), a.end());
for (auto &x : a) {
x = 2 - x;
}
ans = get(a);
for (auto &[u, v] : ans) {
u = n + 1 - u;
v = n + 1 - v;
}
}
std::cout << ans.size() << "\n";
for (auto [u, v] : ans) {
std::cout << u << " " << v << "\n";
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}