Codeforces Round 918 (Div. 4) 补题AK
比赛链接
E题用umap被hack了,F有个简单知识点没学,离青又远了
A 模拟
思路
3个数找只出现一次的,直接上异或代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;
int a, b, c;
void solve() {
cin >> a >> b >> c;
cout << (a ^ b ^ c) << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
// T=1;
while (T--) solve();
return 0;
}
B 模拟
思路
找3个字符中没出现的那个,直接上哈希+枚举代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;
char s[5][5];
void solve() {
forn(i, 1, 3) forn(j, 1, 3) cin >> s[i][j];
forn(i, 1, 3) {
umap<char, int> mp;
forn(j, 1, 3) mp[s[i][j]]++;
forn(j, 'A', 'C') {
if (mp[j] == 0) {
cout << (char) j << endl;
return;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
// T=1;
while (T--) solve();
return 0;
}
C 模拟
思路
就是判断是不是平方数,语法题没什么好说的代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;
ll n;
ll a[N];
double sum;
void solve() {
cin >> n;
sum = 0;
forn(i, 1, n) cin >> a[i], sum += a[i];
ll x = (ll) sqrt(sum);
if (x * x == sum) cy;
else cn;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
// T=1;
while (T--) solve();
return 0;
}
D 思维 模拟
思路
首先把字符全部预处理成c和v发现如果是cvc和cv第一个字符都是c不好区分
如果翻转一下,cvc和vc就很好区分了,直接遍历一遍,再把得到的答案翻转即可
代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;
int n;
char s[N], a[N];
void solve() {
cin >> n;
forn(i, 1, n) cin >> s[i];
forn(i, 1, n) {
if (s[i] == 'a' || s[i] == 'e') a[i] = 'v';
else
a[i] = 'c';
}
reverse(a + 1, a + n + 1);
reverse(s + 1, s + n + 1);
vector<char> ans;
int l = 1;
while (l <= n) {
if (a[l] == 'c') {
ans.push_back('.');
forn(i, l, l + 2) ans.push_back(s[i]);
l += 3;
continue;
}
if (a[l] == 'v') {
ans.push_back('.');
forn(i, l, l + 1) ans.push_back(s[i]);
l += 2;
}
}
reverse(ans.begin(), ans.end());
ans.pop_back();
for (auto i : ans) cout << i;
cout << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
// T=1;
while (T--) solve();
return 0;
}
E 思维 前缀和
思路

直接求一遍这个式子的前缀和,如果两个前缀和相等,那么它们之间的子数组的和为 0
可以用哈希来实现(注意用map,umap会被卡)
代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5;
int T;
ll n;
ll a[N];
ll sum[N];
void solve() {
cin >> n;
forn(i, 1, n) cin >> a[i];
int ok = 0;
map<ll, ll> mp;
forn(i, 1, n) {
if (i & 1) sum[i] = sum[i - 1] + a[i];
else sum[i] = sum[i - 1] - a[i];
if (sum[i] == 0 || mp[sum[i]]) ok = 1;
mp[sum[i]]++;
}
if (ok) cy;
else cn;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
// T=1;
while (T--) solve();
return 0;
}
F 离散化 树状数组/线段树 思维
思路

按左端点排序,再查看每个人右端点经过几条之前条线段,可以转化为区间问题
对于每个人,答案累加上右端点上的值,之后再将区间整体加1,可以使用树状数组+离散化实现
代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const int inf = 0x3f3f3f3f;
const int N = 4e5 + 5;
int T;
ll n;
ll t[N];
ll lowbit(ll x) {
return x & -x;
}
void add(ll x, ll k) {
while (x <= 2 * n) {
t[x] += k;
x += lowbit(x);
}
}
ll sum(ll x) {
ll s = 0;
while (x > 0) {
s += t[x];
x -= lowbit(x);
}
return s;
}
void add(int l, int r, int k) {
add(l, k), add(r + 1, -k);
}
struct node {
ll a, b;
} s[N], ss[N];
vector<ll> v;
bool cmp(node x, node y) {
return x.a < y.a;
}
void solve() {
cin >> n;
forn(i, 1, n) cin >> s[i].a >> s[i].b;
v.clear();
forn(i, 1, n) {
v.push_back(s[i].a);
v.push_back(s[i].b);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
forn(i, 1, n) {
s[i].a = lower_bound(v.begin(), v.end(), s[i].a) - v.begin() + 1;
s[i].b = lower_bound(v.begin(), v.end(), s[i].b) - v.begin() + 1;
}
memset(t, 0, sizeof t);
sort(s + 1, s + n + 1, cmp);
ll ans = 0;
forn(i, 1, n) {
ans += sum(s[i].b);
add(s[i].a, s[i].b, 1);
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
// T=1;
while (T--) solve();
return 0;
}
G 最短路 思维
思路

感觉有种DP的感觉
代码
#include <bits/stdc++.h>
using namespace std;
#define umap unordered_map
#define cy cout << "YES" << endl
#define cn cout << "NO" << endl
#define ll long long
#define forn(i, l, r) for (int i = l; i <= r; i++)
#define forn_(i, l, r) for (int i = l; i >= r; i--)
#define debug(a) cout << #a << "=" << a << endl;
const ll inf = 1e18;
const int N = 1e3 + 5;
int T;
int n, m;
struct edge {
ll to, w;
};
struct node {
ll dis, id, cost;
bool operator<(const node &x) const {
return dis > x.dis;
}
};
vector<edge> g[N];
ll s[N];
ll dist[N][N];
bool vis[N][N];
void dijkstra() {
memset(vis, 0, sizeof vis);
forn(i, 1, n) forn(j, 1, 1000) dist[i][j] = inf;
dist[1][s[1]] = 0;
priority_queue<node> q;
q.push({0, 1, s[1]});
while (!q.empty()) {
node now = q.top();
q.pop();
ll u = now.id, cost = now.cost;
if (vis[u][cost] || dist[u][cost] == inf) continue;
vis[u][cost] = 1;
for (auto i : g[u]) {
int v = i.to, w = i.w;
ll c = min(s[v], cost);
if (dist[v][c] > dist[u][cost] + w * cost) {
dist[v][c] = dist[u][cost] + w * cost;
q.push({dist[v][c], v, c});
}
}
}
}
void solve() {
cin >> n >> m;
forn(i, 1, n) g[i].clear();
forn(i, 1, m) {
ll u, v, w;
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
}
forn(i, 1, n) cin >> s[i];
dijkstra();
ll ans = inf;
forn(i, 1, 1000) ans = min(ans, dist[n][i]);
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
// T=1;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号