Codeforces Round 927 (Div. 3)
A - Thorns and Coins
解题思路:
出现连续两个障碍之前,所有金币都能拿到。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
void solve()
{
int n;
cin >> n;
string s;
cin >> s;
s = ' ' + s;
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (s[i] == '@')
{
ans++;
}
else if (s[i] == '*')
{
if (i - 1 > 0 && s[i - 1] == s[i])
{
break;
}
}
}
cout << ans << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
B - Chaya Calendar
解题思路:
遍历,找到大于已过当前年的最小倍数。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
void solve()
{
int n;
cin >> n;
vector<ll> a(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
ll cur = 1;
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
cur = a[i] + 1;
}
else
{
ll k = (cur + (a[i] - 1)) / a[i];
cur = k * a[i] + 1;
}
}
cout << cur - 1 << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
C - LR-remainders
解题思路:
从全部开始删不好搞,我们先按步骤走到最后一点,然后反着加起来。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
void solve()
{
ll n, m;
cin >> n >> m;
vector<ll> a(n + 1, 1);
ll ans = 1;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
string s;
cin >> s;
int l = 1;
int r = n;
int idx = 0;
for (auto c : s)
{
if (c == 'L')
{
l++;
}
else
{
r--;
}
}
reverse(s.begin(), s.end());
vector<int> v;
for (auto c : s)
{
if (c == 'L')
{
l--;
ans = ans * a[l] % m;
}
else
{
r++;
ans = ans * a[r] % m;
}
v.push_back(ans);
}
for (int i = v.size() - 1; i >= 0; i--)
{
cout << v[i] << ' ';
}
cout << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
D - Card Game
解题思路:
模拟吐了。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
void solve()
{
int n;
cin >> n;
string jok;
cin >> jok;
map<char, int> q;
q['C'] = 1;
q['D'] = 2;
q['H'] = 3;
q['S'] = 4;
map<int, char> inv;
inv[1] = 'C';
inv[2] = 'D';
inv[3] = 'H';
inv[4] = 'S';
vector<vector<int>> cards(10, vector<int>());
for (int i = 1; i <= 2 * n; i++)
{
string t;
cin >> t;
int x = q[t[1]];
cards[x].push_back(t[0] - '0');
}
for (int i = 1; i <= 4; i++)
{
sort(cards[i].begin(), cards[i].end());
}
// for (int i = 1; i <= 4; i++)
// {
// for (auto x : cards[i])
// {
// cout << x << ' ';
// }
// cout << endl;
// }
vector<pair<string, string>> ans;
for (int i = 1; i <= 4; i++)
{
// cerr << i << endl;
if (q[jok[0]] == i)
{
}
else
{
int len = cards[i].size();
for (int j = len - 1; j >= 1; j -= 2)
{
// cerr << j << ' ';
int a = cards[i].back();
cards[i].pop_back();
int b = cards[i].back();
cards[i].pop_back();
char cb = char('0' + b);
string tb;
tb.push_back(cb);
tb.push_back(inv[i]);
char ca = '0' + a;
string ta;
ta.push_back(ca);
ta.push_back(inv[i]);
ans.push_back({tb, ta});
}
// cerr << endl;
}
}
for (int i = 1; i <= 4; i++)
{
if (q[jok[0]] != i)
{
while (!cards[i].empty())
{
int a = cards[i].back();
cards[i].pop_back();
if (cards[q[jok[0]]].size())
{
int b = cards[q[jok[0]]].back();
cards[q[jok[0]]].pop_back();
char cb = char('0' + b);
string tb;
tb.push_back(cb);
tb.push_back(jok[0]);
char ca = '0' + a;
string ta;
ta.push_back(ca);
ta.push_back(inv[i]);
ans.push_back({ta, tb});
}
else
{
puts("IMPOSSIBLE");
return;
}
}
}
}
if (cards[q[jok[0]]].size())
{
int len = cards[q[jok[0]]].size();
for (int j = len - 1; j >= 1; j -= 2)
{
int a = cards[q[jok[0]]].back();
cards[q[jok[0]]].pop_back();
int b = cards[q[jok[0]]].back();
cards[q[jok[0]]].pop_back();
char cb = char('0' + b);
string tb;
tb.push_back(cb);
tb.push_back(inv[q[jok[0]]]);
char ca = '0' + a;
string ta;
ta.push_back(ca);
ta.push_back(inv[q[jok[0]]]);
ans.push_back({tb, ta});
}
}
for (int i = 1; i <= 4; i++)
{
if (cards[i].size())
{
puts("IMPOSSIBLE");
return;
}
}
for (auto t : ans)
{
cout << t.fi << ' ' << t.se << endl;
}
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
E - Final Countdown
解题思路:
举例:\(12345 \to 12345 + 1234 + 123 + 12 + 1 = 13715\)
显然,全部加起来,边除边模往上进位即可。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
void solve()
{
int n;
cin >> n;
string s;
cin >> s;
for (int i = 0; i < n; i++)
{
if (s[i] != '0')
{
s = s.substr(i);
break;
}
}
n = s.size();
s = ' ' + s;
vector<ll> pre(n + 10, 0);
for (int i = 1; i <= n; i++)
{
pre[i] = pre[i - 1] + (s[i] - '0');
}
string ans;
ll res = 0;
for (int i = n; i > 0; i--)
{
char c = (pre[i] % 10) + '0';
ans += c;
if (i > 1)
{
pre[i - 1] += pre[i] / 10;
}
else
{
res += pre[i] / 10;
}
}
while (res)
{
char c = (res % 10) + '0';
res /= 10;
ans += c;
}
reverse(ans.begin(), ans.end());
cout << ans << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
F - Feed Cats
解题思路:
\(dp[i]:考虑前i个点的选取,能得到的最大线段数。\)
- 如果选第\(i\)个点,那么我们要找到覆盖点\(i\)的线段中,最小的左端点位置\(idx\),\(dp[i] \leftarrow dp[idx - 1] + cnt\)。其中,\(cnt\)为经过点\(i\)的线段数量。
- 如果不选第\(i\)个点,就是考虑前\(i\)个点得到的最大答案\(dp[i] \leftarrow dp[i - 1]\)。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
void solve()
{
int n, m;
cin >> n >> m;
vector<vector<int>> l(n + 1, vector<int>());
vector<int> d(n + 10);
for (int i = 1; i <= m; i++)
{
int a, b;
cin >> a >> b;
l[b].push_back(a);
d[a]++;
d[b + 1]--;
}
for (int i = 1; i <= n; i++)
{
d[i] += d[i - 1];
}
// 左侧最远可影响i处的点。
vector<int> w(n + 10, n + 1);
for (int i = n; i; i--)
{
w[i] = min(i, w[i + 1]);
for (auto x : l[i])
{
w[i] = min(w[i], x);
}
}
vector<int> dp(n + 1);
for (int i = 1; i <= n; i++)
{
dp[i] = max(dp[i - 1], dp[w[i] - 1] + d[i]);
}
cout << dp[n] << endl;
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
G - Moving Platforms
解题思路:
\((u,v)\)之间连通情况。
根据题意,\(l_u + ks_u \equiv l_v + ks_v \mod h\)
\[k(s_u - s_v) \equiv l_v - l_u \mod h \\ \]\[k(s_u - s_v) + h y = l_v - l_u \]扩展欧几里得解不定方程,得到\((k_0, y_0)\)。\(gcd((s_u - s_v),h) = d\)
根据裴蜀定理,判断是否有解,如果无解,就无法连边。
特解\((k_0,y_0)\),通解为\((k_0 + t\frac{h}{d},y_0 - t\frac{s_u - s_v}{d})\)
求最小非负整数\(k\),以及合法时间点间隔\(\frac{h}{d}\)。
然后跑最短路。转移时找到最近合法可转移的时间进行转移。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
const ll inf = 1ll << 50;
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
ll g = exgcd(b, a % b, y, x);
y -= a / b * x;
return g;
}
struct node
{
ll v, st, step;
};
void solve()
{
ll n, m, h;
cin >> n >> m >> h;
vector<ll> l(n + 1), s(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> l[i];
}
for (int i = 1; i <= n; i++)
{
cin >> s[i];
}
vector<vector<node>> e(n + 1, vector<node>());
for (int i = 1; i <= m; i++)
{
int u, v;
cin >> u >> v;
ll c = l[v] - l[u];
ll a = s[u] - s[v];
ll b = h;
ll x, y;
ll d = exgcd(a, b, x, y);
if (c % d)
{
continue;
}
ll step = abs(b / d);
ll k = c / d % step;
x = x * k % step;
x = ((x % step) + step) % step;
e[u].push_back((node){v, x, step});
e[v].push_back((node){u, x, step});
}
priority_queue<pii, vector<pii>, greater<pii>> q;
vector<ll> dist(n + 1, inf);
dist[1] = 0;
vector<bool> vis(n + 1);
q.push({dist[1], 1});
while (q.size())
{
auto t = q.top();
q.pop();
int u = t.se;
if (vis[u])
{
continue;
}
vis[u] = true;
for (auto x : e[u])
{
ll v = x.v;
ll sp = x.st;
ll step = x.step;
// 找到最小合法转移时间
if (dist[u] > sp)
{
sp += (dist[u] - sp + (step - 1)) / step * step;
}
if (dist[v] > sp + 1)
{
dist[v] = sp + 1;
q.push({dist[v], v});
}
}
}
if (dist[n] >= inf)
{
puts("-1");
}
else
{
cout << dist[n] << endl;
}
}
int main()
{
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
标签:int,ll,Codeforces,long,back,vector,using,Div,927
From: https://www.cnblogs.com/value0/p/18021816