Codeforces Round 947 (Div. 1 + Div. 2)

A. Bazoka and Mocha's Array

题目要求

  • 一个长度为n的数组,你可以执行零次或者多次操作,使得数组按照从小到大排序

  • 操作是选择数组的前缀和后缀,将前缀和后缀翻转

例如,如果 a=[3,1,4,1,5]a=[3,1,4,1,5] ,我们可以选择 x=[3,1] 和 y=[4,1,5],设置a:=y+x=[4,1,5,3,1]

思路

  • 如果数组一开始就是从小到大的,那就直接输出“YES”

  • 如果数组一开始不是从小到大的,可以如果满足,那么只需要进行一次操作,就可以将数组变为从小到大。选择的前缀和后缀需要满足,都是从小到大的并且后缀的最后一个元素要小于前缀的第一个元素。

  • 我们不难发现,只需要找到数组中第一个a_i > a_{i-1}的位置即可,然后判断是否满足我们上述分析的条件。

代码

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl "\n"
#define debug(x) cout << #x << " " << x << endl
void solve()
{
	int n;
	cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	// 判断是否一开始就是从小到大有序的
	if (is_sorted(a.begin(), a.end())) {
		cout << "YES" << endl;
		return;
	}
	// 找到a_i > a_{i+1}的第一个位置,判断满足与否
	for (int i = 0; i < n - 1; i++) {
		if (a[i] > a[i + 1]) {
			if (is_sorted(a.begin(), a.begin() + i + 1) &&
				is_sorted(a.begin() + i + 1, a.end()) &&
				a[n - 1] <= a[0]) {
				cout << "YES" << endl;
				return;
			}
			else {
				cout << "NO" << endl;
				return;
			}
		}
	}
}
signed main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
	return 0;
}

B. 378QAQ and Mocha's Array

题目要求

  • 有一个长度为n的数组a,要求判断数组是否是美丽的。

  • 数组中如果存在两个数,使得每一个数能被这两个数中的任意一个整除

思路

  • 首先数组中最小的那个数一定会被选择。

  • 接下来,我们把不能被我们第一个选择的这个最小的数整除的都放到另一个数组中。那么问题就转化成了在另一个数组中选择一个数,使得另一个数组中的任意一个数能被选择的这个数整除

  • 那就是再在这个数组中选一个最小的数,判断即可。

代码

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl "\n"
#define debug(x) cout << #x << " " << x << endl
void solve()
{
	int n;
	cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	// 找到数组a中最小的那个数
	int min_one = *min_element(a.begin(), a.end());
	// 把不能被min_one整除的数存在数组b中
	vector<int> b;
	for (int i = 0; i < n; i++) {
		if (a[i] % min_one != 0) {
			b.push_back(a[i]);
		}
	}
	// 同理在b数组中按照上述操作
	if (b.size() == 0) {
		cout << "YES" << endl;
		return;
	}
	int min_two = *min_element(b.begin(), b.end());
	for (int i = 0; i < b.size(); i++) {
		if (b[i] % min_two != 0) {
			cout << "NO" << endl;
			return;
		}
	}
	cout << "YES" << endl;
}
signed main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
	return 0;
}

C. Chamo and Mocha's Array

题目要求

  • 有一个长度为n的数组a,你需要进行操作,使得数组a中的元素都相同

  • 可以进行如下操作,选择一个区间[l,r],然后将这一区间的数全变为这个区间的中位数。

  • 问,能否在操作多次后满足元素都相同的前提下,使得元素最大,最大元素是多少。

思路

  • 记录数组中所有连续的三个数 ai−1,ai,ai+1的中位数的最大值即为答案

代码

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl "\n"
#define debug(x) cout << #x << " " << x << endl
void solve()
{
	int n;
	cin >> n;
	vector<int> a(n + 1);
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	if (n == 2)
	{
		cout << min(a[1], a[2]) << endl;
		return;
	}
	for (int i = 1; i <= n - 2; i++)
	{
		vector<int> b;
		b.push_back(a[i]);
		b.push_back(a[i + 1]);
		b.push_back(a[i + 2]);
		sort(b.begin(), b.end());
		ans = max(ans, b[1]);
	}
	cout << ans << endl;
}
signed main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值