Rayan Programming Contest 2024 - Selection (Codeforces Round 989, Div. 1 + Div. 2) 题解 (A~E)
A. King Keykhosrow's Mystery
上限是
#include <bits/stdc++.h>
void solve()
{
int a, b; std::cin >> a >> b;
int l = std::lcm(a, b);
for(int i = std::min(a, b); i <= l; i++)
{
if(i % a == i % b)
{
std::cout << i << "\n";
return;
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
B. Rakhsh's Revival
贪心,每次
#include <bits/stdc++.h>
void solve()
{
int n, m, k; std::cin >> n >> m >> k;
std::string s; std::cin >> s;
int cnt = 0, ans = 0;
for(int i = 0; i < n; i++)
{
if(s[i] == '0') cnt++;
if(s[i] == '1') cnt = 0;
if(cnt == m)
{
i = std::min(n, i + k - 1);
cnt = 0;
ans++;
}
}
std::cout << ans << "\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
C. Trapped in the Witch's Labyrinth
整个网络可以看成一个有向图,超出网络视为终点,按照给出的字母连反边,从终点开始搜索,路上经过的点代表着最后都会走出这张图,所以不能成为答案,标记一下。处理完这些之后,再处理问号,对于一个问号,如果它上下左右的点都被标记了,说明它最后也会走出去,也不能成为答案。把这些点抛去之后的点就是答案。
#include <bits/stdc++.h>
void solve()
{
int n, m; std::cin >> n >> m;
std::vector<std::string> s(n);
for(int i = 0; i < n; i++) std::cin >> s[i];
std::vector<std::vector<int>> adj(n * m + 1);
int ed = n * m;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
int x = i + (s[i][j] == 'D') - (s[i][j] == 'U');
int y = j + (s[i][j] == 'R') - (s[i][j] == 'L');
if(x >= n || y >= m || x < 0 || y < 0) adj[ed].emplace_back(i * m + j);
else adj[x * m + y].emplace_back(i * m + j);
}
}
std::vector<int> vis(n * m);
int ans = n * m, st = n * m;
std::queue<int> q;
q.emplace(st);
while(!q.empty())
{
int x = q.front(); q.pop();
for(auto y : adj[x])
{
vis[y] = 1;
ans--;
q.emplace(y);
}
}
std::array<int, 4> dx{0, -1, 0, 1}, dy{-1, 0, 1, 0};
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++) if(s[i][j] == '?')
{
int cnt = 0;
for(int dir = 0; dir < 4; dir++)
{
int x = i + dx[dir], y = j + dy[dir];
if(x >= n || y >= m || x < 0 || y < 0 || vis[x * m + y]) cnt++;
}
if(cnt == 4) ans--;
}
}
std::cout << ans << "\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
D. Darius' Wisdom
不妨倒着考虑每一位会是什么。可以先用三个
对于一个位置,如果它应该是
#include <bits/stdc++.h>
void solve()
{
int n; std::cin >> n;
std::vector<int> a(n);
for(int i = 0; i < n; i++) std::cin >> a[i];
std::array<std::set<int>, 3> pos;
for(int i = 0; i < n; i++) pos[a[i]].emplace(i);
std::vector<std::pair<int, int>> ans;
auto modify = [&](int idx) -> void
{
if(!pos[2].empty())
{
if(a[idx] == 2) pos[2].erase(idx);
else if(a[idx] == 1)
{
int tmp = *pos[2].begin();
std::swap(a[idx], a[tmp]);
pos[2].erase(tmp);
pos[1].erase(idx);
pos[1].emplace(tmp);
ans.emplace_back(idx, tmp);
}
else
{
int tmp1 = *pos[1].begin(), tmp2 = *pos[2].begin();
std::swap(a[idx], a[tmp1]);
std::swap(a[idx], a[tmp2]);
pos[2].erase(tmp2);
pos[1].erase(tmp1);
pos[1].emplace(tmp2);
pos[0].erase(idx);
pos[0].emplace(tmp1);
ans.emplace_back(idx, tmp1);
ans.emplace_back(idx, tmp2);
}
}
else
{
if(a[idx] == 1) pos[1].erase(idx);
else
{
int tmp = *pos[1].begin();
std::swap(a[idx], a[tmp]);
pos[1].erase(tmp);
pos[0].erase(idx);
pos[0].emplace(tmp);
ans.emplace_back(idx, tmp);
}
}
};
for(int i = n - 1; i >= 0; i--)
{
if(pos[1].empty() && pos[2].empty()) break;
modify(i);
}
std::cout << ans.size() << "\n";
for(auto [x, y] : ans)
std::cout << x + 1 << " " << y + 1 << "\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
E. Permutations Harmony
首先可以把
然后注意到
接下来考虑
首先如果
我们可以算出来每一列的和是多少,是
考虑
#include <bits/stdc++.h>
using i64 = long long;
void solve()
{
int n, k; std::cin >> n >> k;
i64 fac = 1;
for(int i = 1; i <= n && fac < k + 10; i++)
fac *= i;
if(fac < k)
{
std::cout << "NO\n";
return;
}
if(n == 1)
{
std::cout << "YES\n";
std::cout << "1\n";
return;
}
if(k % 2 == 0)
{
std::cout << "YES\n";
std::vector<int> a(n);
std::iota(a.begin(), a.end(), 1);
for(int i = 0; 2 * i < k; i++)
{
for(int j = 0; j < n; j++) std::cout << a[j] << " \n"[j == n - 1];
for(int j = 0; j < n; j++) std::cout << n + 1 - a[j] << " \n"[j == n - 1];
std::next_permutation(a.begin(), a.end());
}
return;
}
if(k == 1 || k == fac - 1)
{
std::cout << "NO\n";
return;
}
if((n + 1) % 2)
{
std::cout << "NO\n";
return;
}
std::cout << "YES\n";
std::vector<int> a(n);
for(int i = 0; i < n; i++) a[i] = i + 1;
std::set<std::vector<int>> vis;
for(int i = 0; i < n; i++) a[i] = (n + 1) * 3 / 2 - a[i];
std::ranges::reverse(a);
std::vector<int> b(n);
for(int i = a[0] - 1, j = 0; i; i--, j++) b[j] = i;
for(int i = n, j = a[0] - 1; j < n; i--, j++) b[j] = i;
vis.emplace(b);
for(int i = 0; i < n; i++) b[i] = a[i] - b[i];
vis.emplace(b);
for(int i = 0; i < n; i++) b[i] = i + 1;
std::ranges::reverse(b);
vis.emplace(b);
std::ranges::reverse(b);
auto ans = vis;
while(ans.size() < k)
{
std::vector<int> c(b);
for(int j = 0; j < n; j++) c[j] = n + 1 - c[j];
if(!vis.contains(b) && !vis.contains(c))
{
ans.emplace(b);
ans.emplace(c);
}
std::next_permutation(b.begin(), b.end());
}
for(auto p : ans) for(int i = 0; i < n; i++) std::cout << p[i] << " \n"[i == n - 1];
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
分类:
比赛
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)