Loading

AtCoder Beginner Contest 393



A - Poisonous Oyster

题意

两个人\(A,B\)\(4\)种东西,\(A\)\(1,2\)\(B\)\(1,3\),给出两人状态\(fine\)\(sick\),问哪种食物有毒

思路

模拟

代码

点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e5 + 5;

void solve()
{
	string s, t;
	cin >> s >> t;
	if (s == "fine" && t == "fine")
	{
		cout << 4 << endl;
		return;
	}
	if (s == "fine" && t == "sick")
	{
		cout << 3 << endl;
		return;
	}
	if (s == "sick" && t == "fine")
	{
		cout << 2 << endl;
		return;
	}
	cout << 1 << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int __ = 1;
	//cin >> __;
	while (__--)
	{
		solve();
	}

	return 0;
}

B - A..B..C

题意

给定字符串\(s\),求:

思路

按题意模拟

代码

点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e5 + 5;

void solve()
{
	string s;
	cin >> s;
	int ans = 0;
	for (int i = 0; i < s.length() - 2; i++)
	{
		if (s[i] != 'A')
		{
			continue;
		}
		for (int j = i + 1; j < s.length() - 1; j++)
		{
			if (s[j] != 'B')
			{
				continue;
			}
			for (int k = j + 1; k < s.length(); k++)
			{
				if (s[k] != 'C')
				{
					continue;
				}
				if (j - i == k - j)
				{
					ans++;
				}
			}
		}
	}
	cout << ans << endl;

}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int __ = 1;
	//cin >> __;
	while (__--)
	{
		solve();
	}

	return 0;
}

C - Make it Simple

题意

给定\(n\)个顶点\(m\)条边的无向图,求把它变成简单图要删的边数

思路

删自环和重边

代码

点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e5 + 5;

void solve()
{
	int n, m, ans = 0;
	cin >> n >> m;
	set<pii> s;
	for (int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		if (u < v)
		{
			swap(u, v);
		}
		if (u == v)
		{
			ans++;
		}
		else if (s.count({ u,v }))
		{
			ans++;
		}
		else
		{
			s.insert({ u,v });
		}
	}
	cout << ans << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int __ = 1;
	//cin >> __;
	while (__--)
	{
		solve();
	}

	return 0;
}

D - Swap to Gather

题意

给定\(01\)\(s\),每次操作可以交换\(s_i\)\(s_{i+1}\)。求使所有\(1\)都连续的最小操作数

思路

往最中间的\(1\)移——中位数在最小化绝对差之和中的最优性质

代码

点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e5 + 5;

void solve()
{
	int n, ans = 0;
	string s;
	cin >> n >> s;
	vector<int> p;
	for (int i = 0; i < s.length(); i++)
	{
		if (s[i] == '1')
		{
			p.push_back(i);
		}
	}
	int m = p.size(), mid = p[m / 2];
	for (int i = 0; i < m; i++)
	{
		ans += abs(p[i] - (mid - m / 2 + i)); // 后者为目标点
	}
	cout << ans << endl;

}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int __ = 1;
	//cin >> __;
	while (__--)
	{
		solve();
	}

	return 0;
}

E - GCD of Subset

题意

给定长为\(n\)的序列\(a\),和正整数\(k\)。对于每个\(i(1\le i\le n)\):从\(a\)中选择包括\(a_i\)\(k\)个元素,求所选元素的\(GCD\)的最大值

思路

每个元素都算一遍因子会超时,那就处理数据范围内所有数作因子的次数。详情见代码

代码

点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e6 + 5;

void solve()
{
	int n, k;
	cin >> n >> k;
	vector<int> a(n), fre(mxn, 0);
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
		fre[a[i]]++;
	}
	vector<int> cnt(mxn, 0); // cnt[i]表示i作因子的次数
	for (int i = 1; i < mxn; i++)
	{
		for (int j = i; j < mxn; j += i) // 枚举倍数
		{
			cnt[i] += fre[j];
		}
	}
	vector<int> ans(mxn, 0);
	for (int i = mxn; i >= 1; i--) // 要最大就逆序枚举
	{
		if (cnt[i] >= k)
		{
			for (int j = i; j < mxn; j += i)
			{
				if (!ans[j])
				{
					ans[j] = i;
				}
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		cout << ans[a[i]] << endl;
	}
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int __ = 1;
	//cin >> __;
	while (__--)
	{
		solve();
	}

	return 0;
}

F - Prefix LIS Query

题意

给定长为\(n\)的序列\(a\),和\(q\)次查询,每次查询给定\(r_i,x_i\)
考虑\((a_1,a_2,···,a_{r_i})\)的一个严格递增子序列(不一定连续),其每个元素都不大于\(x_i\)。求这个子序列的最大长度

思路

详情见代码

代码

点击查看代码
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e6 + 5;

void solve()
{
	int n, q;
	cin >> n >> q;
	vector<int> a(n);
	for (auto& i : a) cin >> i;
	vector<vector<pii>> Q(n);
	for (int i = 0; i < q; i++)
	{
		int r, x;
		cin >> r >> x;
		Q[--r].push_back(make_pair(i, x));
	}
	vector<int> lis(n, 1e18), ans(q);
	for (int i = 0; i < n; i++)
	{
		// 将a[i]插入当前的lis
		auto p = lower_bound(lis.begin(), lis.end(), a[i]);
		*p = a[i];
		// 在长度为i的子序列中查询
		for (auto& [idx, x] : Q[i])
		{
			ans[idx] = upper_bound(lis.begin(), lis.end(), x) - lis.begin();
		}
	}
	for (int i = 0; i < q; i++)
	{
		cout << ans[i] << 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/abc393

posted @ 2025-02-16 20:13  _SeiI  阅读(34)  评论(0)    收藏  举报