IAEPC Preliminary Contest (Codeforces Round 999, Div. 1 + Div. 2)
A - Kevin and Arithmetic
题意
给定\(n\)个整数\(a_1,a_2,···,a_n\),和初始化为\(0\)的整数\(s\)。将\(a_i\)加到\(s\)上,若得到的\(s\)是偶数,加\(1\)分,然后\(s%=2\)。重新排列\(a\),使得分最大化
思路
详情见代码
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
void solve()
{
	int n, cnt = 0;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int a;
		cin >> a;
		if (a & 1)
		{
			cnt++;
		}
	}
	if (!cnt)
	{
		cout << 1 << endl;
		return;
	}
	if (cnt == n)
	{
		cout << n - 1 << endl;
		return;
	}
	cout << cnt + 1 << endl;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int T = 1;
	cin >> T;
	while (T--)
	{
		solve();
	}
	return 0;
}
B - Kevin and Arithmetic
题意
给定\(n\)根一直长度的棍子,问是否能挑\(4\)根组成等腰梯形(长方形和正方形也是等腰梯形)。
思路
找最大腰,然后找一条最小边,这样最优。用\(A,B,C\)表示上底边,腰和下底边,则要满足\(A+2B>C\)
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
void solve()
{
	int n;
	cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	sort(a.begin(), a.end());
	int A, B, p;
	for (int j = n - 1; j > 0; j--)
	{
		if (a[j] == a[j - 1])
		{
			B = a[j];
			p = j;
			for (int i = 0; i < n; i++)
			{
				if (i == p || i == p - 1)
				{
					continue;
				}
				A = a[i];
				auto q = lower_bound(a.begin(), a.end(), A);
				while (q - a.begin() == i || q - a.begin() == p || q - a.begin() == p - 1)
				{
					q++;
				}
				if (q == a.end() || a[q - a.begin()] >= A + 2 * B)
				{
					continue;
				}
				cout << A << " " << B << " " << B << " " << a[q - a.begin()] << endl;
				return;
			}
		}
	}
	cout << -1 << endl;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int T = 1;
	cin >> T;
	while (T--)
	{
		solve();
	}
	return 0;
}
C - Kevin and Puzzle
题意
\(n\)个人站成一排,\(a_i\)表示第\(i\)个人说左边(包括自己),有多少人是骗子(骗子可以说真话也可以说谎)。两个骗子不能相邻。问有多少组合。
思路
详情见代码
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 2e5 + 5;
const int mod = 998244353;
int dp[mxn][2]; // dp[i][0]表示到第i个人并且他不诚实的方案数
int cnt[mxn]; // cnt[i]表示如果第i个人说谎,[1,i)说谎的人数
void clear(int n)
{
	for (int i = 1; i <= n; i++)
	{
		dp[i][0] = dp[i][1] = 0;
	}
}
void solve()
{
	int n;
	cin >> n;
	vector<int> a(n + 1);
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	if (a[1])
	{
		cnt[1] = dp[1][0] = 1;
	}
	else
	{
		dp[1][1] = dp[1][0] = cnt[1] = 1;
	}
	for (int i = 2; i <= n; i++)
	{
		// 当前不诚实
		dp[i][0] = dp[i - 1][1]; // 如果不诚实了,上一个人一定诚实
		cnt[i] = a[i - 1] + 1;
		// 当前诚实
		if (a[i] < i)
		{
			if (a[i] == a[i - 1]) // 上一个人诚实
			{
				dp[i][1] = dp[i - 1][1];
			}
			if (a[i] == cnt[i - 1]) // 上一个人说谎
			{
				dp[i][1] += dp[i - 1][0];
				dp[i][1] %= mod;
			}
		}
	}
	cout << (dp[n][0] + dp[n][1]) % mod << endl;
	clear(n);
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int T = 1;
	cin >> T;
	while (T--)
	{
		solve();
	}
	return 0;
}
D - Kevin and Numbers
题意
给定长度为\(n\)的正整数序列\(a\),可以执行以下操作任意次:选择两个数\(x,y(|x-y|\le 1)\)删除,添加一个数\(x+y\)。问能否得到长度为\(m\)的序列\(b\)
思路
注意\(|x-y|\le 1\)这个条件,这让我们可以拆解\(b\)——如果\(b_i\)是偶数,那只能拆成两个\(\frac {b_i} 2\);如果\(b_i\)是奇数,那只能拆成\(\frac {b_i} 2\)和\(\frac {{b_i}+1} 2\)
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 2e5 + 5;
void solve()
{
	int n, m, A = 0, B = 0;
	cin >> n >> m;
	priority_queue<int> a, b;
	for (int i = 0; i < n; i++)
	{
		int x;
		cin >> x;
		A += x;
		a.push(x);
	}
	for (int i = 0; i < m; i++)
	{
		int x;
		cin >> x;
		B += x;
		b.push(x);
	}
	if (A != B)
	{
		cout << "NO" << endl;
		return;
	}
	while (a.size() && b.size())
	{
		int t = b.top();
		b.pop();
		if (t == a.top())
		{
			a.pop();
		}
		else if (t < a.top())
		{
			cout << "NO" << endl;
			return;
		}
		else
		{
			b.push(t >> 1);
			b.push(t + 1 >> 1);
		}
	}
	if (b.size())
	{
		cout << "NO" << endl;
		return;
	}
	cout << "YES" << endl;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int T = 1;
	cin >> T;
	while (T--)
	{
		solve();
	}
	return 0;
}

                
            
        
浙公网安备 33010602011771号