Codeforces Round 479 (Div. 3) 补题 AK

比赛链接

A 模拟

思路

直接模拟就行

代码
#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, k;
void solve() {
	cin >> n >> k;

	while (k--) {
		if (n % 10 == 0) n /= 10;
		else n--;
	}

	cout << n;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//cin >> T;
	T = 1;

	while (T--) solve();
	return 0;
}

B 哈希 模拟

思路 直接用哈希算每个出现的次数,再统计答案即可
代码
#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;
string s, ans;
umap<string, int> mp;
int cnt;
void solve() {
	cin >> n >> s;
	s = ' ' + s;
	forn(i, 1, n - 1) mp[s.substr(i, 2)]++;

	for (auto [i, j] : mp) {
		if (j > cnt) {
			cnt = j;
			ans = i;
		}
	}

	cout << ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//cin >> T;
	T = 1;

	while (T--) solve();
	return 0;
}

C 思维 排序

思路 排序输出第k个就行了,注意特判第k个和k+1是不是相同的

然后还有特判k=0的情况

代码
#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, k;
int a[N];
void solve() {
	cin >> n >> k;
	forn(i, 1, n) cin >> a[i];

	a[0] = 1;
	sort(a + 1, a + n + 1);
	if (a[k] == a[k + 1]) a[k] = -1;
	if (k == 0 && a[1] == 1) a[k] = -1;

	cout << a[k];
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//cin >> T;
	T = 1;

	while (T--) solve();
	return 0;
}

D 拓扑排序

思路

image

代码
#include <bits/stdc++.h>
using namespace std;
#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--)
const int N = 2e5 + 5;
ll T;

int h[N], idx;
struct node {
	int to, ne;
} e[N];

ll n;
ll a[N];
ll in[N];
vector<ll> ans;
void add(int u, int v) {
	e[++idx].to = v;
	e[idx].ne = h[u];
	h[u] = idx;
	in[v]++;
}
void topsort() {
	queue<ll> q;
	forn(i, 1, n) if (in[i] == 0) q.push(i);

	while (!q.empty()) {
		ll u = q.front();
		q.pop();
		ans.push_back(u);
		for (int i = h[u]; i; i = e[i].ne) {
			ll v = e[i].to;
			if (--in[v] == 0) q.push(v);
		}
	}
}
void solve() {
	cin >> n;
	forn(i, 1, n) cin >> a[i];

	forn(i, 1, n) {
		forn(j, 1, n) {
			if (a[i] * 2 == a[j] || a[j] * 3 == a[i]) add(i, j);
		}
	}
	topsort();

	for (auto i : ans) cout << a[i] << ' ';
}

int main() {
	//cin >> T;
	T = 1;

	while (T--) {
		solve();
	}

	return 0;
}

E 思维 搜索

思路 一个圈内所有点的度数均为 2,且大小要大于等于3

直接搜索,顺便记录连通块大小和是否入度全为2,等到每个连通块搜索完再判断是否是

代码
#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;

vector<int> g[N];
int ok;
int siz;
bool is[N];
int in[N];
void dfs(int u) {
	if (is[u]) return;
	is[u] = 1, siz++;

	if (in[u] != 2) ok = 0;
	for (auto v : g[u]) dfs(v);
}
int n, m;
int ans;
void solve() {
	cin >> n >> m;
	forn(i, 1, m) {
		int u, v;
		cin >> u >> v;
		in[u]++, in[v]++;
		g[u].push_back(v);
		g[v].push_back(u);
	}

	int cnt = 0;
	forn(i, 1, n) {
		if (is[i]) continue;
		cnt++;
		ok = 1;
		siz = 0;
		dfs(i);
		if (ok && siz >= 3) ans++;
	}

	cout << ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//cin >> T;
	T = 1;

	while (T--) solve();
	return 0;
}

F 线性DP

思路 注意本题卡uamp!!!

题目有两问,定义一个结构体,表示以i结尾的最大序列长度为v,上一个数的标号是id

这样就能输出答案了,转移方程:x表示a[i]-1的上一个位置,f[i].id = x,f[i].v = f[x].v + 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 = 2e5 + 5;

int n;
int a[N];
map<int, int> mp;
int ans;
struct node {
	int v, id;
} f[N];
vector<int> res;
int main() {
	cin >> n;
	forn(i, 1, n) {
		cin >> a[i];
		int x = mp[a[i] - 1];
		f[i].id = x;
		f[i].v = f[x].v + 1;
		ans = max(ans, f[i].v);
		mp[a[i]] = i;
	}

	forn_(i, n, i) {
		if (f[i].v == ans) {
			int x = i;
			while (x != 0) res.push_back(x), x = f[x].id;
			break;
		}
	}

	cout << ans << endl;
	reverse(res.begin(), res.end());
	for (auto i : res) cout << i << ' ';
	return 0;
}
posted @ 2023-12-27 22:10  史上最速败犬  阅读(8)  评论(0)    收藏  举报