AtCoder Beginner Contest 395
A - Strictly Increasing?
题意
思路
模拟
代码
点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
#define endl '\n'
const int mxn = 1e6 + 5;
vector<int> p[mxn];
void solve()
{
int n, ans = LLONG_MAX;
cin >> n;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
p[x].push_back(i);
}
bool f = false;
for (int i = 0; i < mxn; i++)
{
if (p[i].size() <= 1)
{
continue;
}
f = true;
for (int j = 1; j < p[i].size(); j++)
{
ans = min(ans, p[i][j] - p[i][j - 1] + 1);
}
}
cout << (f ? ans : -1) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int __ = 1;
//cin >> __;
while (__--)
{
solve();
}
return 0;
}
C - Shortest Duplicate Subarray
题意
思路
记录每种数字出现的位置,相减取最小
代码
点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
#define endl '\n'
const int mxn = 1e6 + 5;
vector<int> p[mxn];
void solve()
{
int n, ans = LLONG_MAX;
cin >> n;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
p[x].push_back(i);
}
bool f = false;
for (int i = 0; i < mxn; i++)
{
if (p[i].size() <= 1)
{
continue;
}
f = true;
for (int j = 1; j < p[i].size(); j++)
{
ans = min(ans, p[i][j] - p[i][j - 1] + 1);
}
}
cout << (f ? ans : -1) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int __ = 1;
//cin >> __;
while (__--)
{
solve();
}
return 0;
}
D - Pigeon Swap
题意
思路
用\(p_i\)表示\(i\)号鸽子所在的巢的位置,\(v_i\)表示第\(i\)个位置是几号巢,\(pv_i\)表示\(i\)号巢的位置
代码
点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
#define endl '\n'
const int mxn = 2e5 + 5;
void solve()
{
int n, q;
cin >> n >> q;
vector<int> p(n + 1), v(n + 1), pv(n + 1);
iota(p.begin(), p.end(), 0);
iota(pv.begin(), pv.end(), 0);
iota(v.begin(), v.end(), 0);
while (q--)
{
int op, a, b;
cin >> op;
if (op == 1)
{
cin >> a >> b;
p[a] = pv[b];
}
else if (op == 2)
{
cin >> a >> b;
swap(v[pv[a]], v[pv[b]]);
swap(pv[a], pv[b]);
}
else
{
cin >> a;
cout << v[p[a]] << endl;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int __ = 1;
//cin >> __;
while (__--)
{
solve();
}
return 0;
}
E - Flip Edge
题意
思路
建立正图和反图,边权为\(1\),最后再用权为\(x\)的边连接正反图中对应的点。这样走权为\(x\)的边就相当于实现了“反转”操作。然后从正图起点开始,跑最短路,正图终点与反图终点取最小
代码
点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
#define endl '\n'
typedef pair<int, int> pii;
const int mxn = 2e5 + 5;
struct edge
{
int v, w;
edge(int v, int w)
{
this->v = v;
this->w = w;
}
};
void solve()
{
int n, m, x;
cin >> n >> m >> x;
vector<vector<edge>> g(2 * n);
for (int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
u--, v--;
g[u].push_back(edge(v, 1));
g[v + n].push_back(edge(u + n, 1));
}
for (int u = 0; u < n; u++)
{
g[u].push_back(edge(u + n, x));
g[n + u].push_back(edge(u, x));
}
priority_queue<pii, vector<pii>, greater<pii>> q;
vector<bool> vis(2 * n, false);
vector<int> dis(2 * n, LLONG_MAX);
dis[0] = 0;
q.push(make_pair(dis[0], 0));
while (q.size())
{
int u = q.top().second;
q.pop();
if (vis[u])
{
continue;
}
vis[u] = true;
for (auto& [v, w] : g[u])
{
if (dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
q.push(make_pair(dis[v], v));
}
}
}
cout << min(dis[n - 1], dis[2 * n - 1]) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int __ = 1;
//cin >> __;
while (__--)
{
solve();
}
return 0;
}
F - Smooth Occlusion
题意
思路
显然只需要处理好上牙,然后取\(h = min(U_i+D_i)\),答案就是处理前的牙齿长度总和\(- n×h\),也可以在处理的过程中计算,最后加上处理下牙的花费。
处理上牙,每次取最短的牙齿 \(i\) ,比较左右牙齿是否满足条件,不满足就讲其变为 \(U_i+x\) (尽量减少操作)
代码
点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
#define endl '\n'
typedef pair<int, int> pii;
const int mxn = 2e5 + 5;
void solve()
{
int n, x, ans = 0;
cin >> n >> x;
vector<int> U(n), D(n);
priority_queue<pii, vector<pii>, greater<pii>> q;
for (int i = 0; i < n; i++)
{
cin >> U[i] >> D[i];
q.push(make_pair(U[i], i));
}
while (q.size())
{
int idx = q.top().second;
q.pop();
if (idx < n - 1 && U[idx + 1] - U[idx]>x)
{
ans += U[idx + 1] - (U[idx] + x);
U[idx + 1] = U[idx] + x;
q.push(make_pair(U[idx + 1], idx + 1));
}
if (idx && U[idx - 1] - U[idx] > x)
{
ans += U[idx - 1] - (U[idx] + x);
U[idx - 1] = U[idx] + x;
q.push(make_pair(U[idx - 1], idx - 1));
}
}
int minn = LLONG_MAX;
for (int i = 0; i < n; i++)
{
minn = min(minn, U[i] + D[i]);
}
for (int i = 0; i < n; i++)
{
ans += U[i] + D[i] - minn;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int __ = 1;
//cin >> __;
while (__--)
{
solve();
}
return 0;
}






浙公网安备 33010602011771号