Loading

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;
}


比赛链接 https://atcoder.jp/contests/abc395

posted @ 2025-03-02 22:06  _SeiI  阅读(38)  评论(0)    收藏  举报