Codeforces Round #826 (Div. 3) A ~D

A. Compare T-Shirt Sizes

题目链接:

Problem - A - Compare T-Shirt Sizes

题面:

在这里插入图片描述

题目大意:

比较两件衣服的大小

思路:

方法一:直接暴力打表
方法二:因为方法一过于暴力,对方法一进行改进,令"X"=1,S=2,L=4,M=3,
将衣服尺寸转换为数值和(注意当存在S时,将数值取负)。
转换式子不唯一,只需考虑各个尺寸的值是否相同即可

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 1e5 + 10;
const ll mod = 1e11 + 3;
const double PI = acos(-1);
#define IOS std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
map<char, int>mp;
void solve() {
	mp['X'] = 1, mp['S'] = 2, mp['M'] = 3, mp['L'] = 4;
	string s1, s2;
	cin >> s1 >> s2;
	int cnt1 = 0, cnt2 = 0;
	for (int i = 0; i < s1.length(); i++) {
		cnt1 += mp[s1[i]];
		if (s1[i] == 'S') cnt1 = -cnt1;
	}
	for (int i = 0; i < s2.length(); i++) {
		cnt2 += mp[s2[i]];
		if (s2[i] == 'S') cnt2 = -cnt2;
	}
	if (cnt1 < cnt2) cout << "<\n";
	else if (cnt1 == cnt2) cout << "=\n";
	else if (cnt1 > cnt2) cout << ">\n";
}
int main() {
	IOS;
	int t;
	cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}

B.Funny Permutation

题目链接:

Problem - B - Funny Permutation

题面:

在这里插入图片描述

题目大意:

构造一个全排列p,使对于每个pi,满足pi-1 = pi + 1或pi-1 = pi - 1 并且pi+1 = pi + 1或pi+1 = pi - 1并且对于每个pi,满足pi≠i

思路:

1.显然我们能够发现当n = 3时,构造不出,直接输出-1
2.当n为偶数时,直接逆序输出1~n
3.当n为奇数时,直接逆序不行,那我们可以将1~n的后半部分提前并逆序输出,再将前半部分顺序输出

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 1e5 + 10;
const ll mod = 1e11 + 3;
const double PI = acos(-1);
#define IOS std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void solve() {
	int n;
	cin >> n;
	if (n == 3) {
		cout << "-1\n";
		return ;
	}
	if (n % 2 == 0) {
		for (int i = n; i >= 1; i--) {
			cout << i << " ";
		}
		cout << "\n";
	} else {
		for (int i = n; i > n / 2 + 1; i--) {
			cout << i << " ";
		}
		for (int i = 1; i <= n / 2 + 1; i++) cout << i << " ";
		cout << "\n";
	}
}
int main() {
	IOS;
	int t;
	cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}

C. Minimize the Thickness

题目链接:

Problem - C - Minimize the Thickness

题面:

在这里插入图片描述

题目大意:

给定一个n个元素的数组,将数组分成若干部分,使得每个部分的数值之和相等,而这个数组的价值为各个部分长度的最大值,求数组的最小价值。注意:每个部分都是连贯的,例如[a[1],a[2],a[3]],而[a[1],a[2],a[4]]则不行

思路:

很显然,解这道题需要知道每个部分内元素的数值和,而因为每个部分都是连贯的,所以肯定需要用到数组的前缀和,所以先存下数组的前缀和。
我们发现n的值不大于2000。数组内元素个数很少,我们可以考虑暴力求解。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 1e5 + 10;
const ll mod = 1e11 + 3;
const double PI = acos(-1);
#define IOS std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
ll a[2005], sum[2005];
void solve() {
	int n;
	cin >> n;
	sum[0] = 0;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		sum[i] = sum[i - 1] + a[i];
	}
	int ans = 3000;
	for (int i = 1; i <= n; i++) {
		int pos = i, cnt = 2, ans1 = i;
		int j;
		for (j = i + 1; j <= n; j++) {
			if (sum[j] == sum[i] * cnt) {
				ans1 = max(ans1, j - pos);
				pos = j;
				cnt++;
			} else if (sum[j] > sum[i] * cnt) {
				break;
			}
		}
		if (j >= n && sum[n] == sum[i] * (cnt - 1)) ans = min(ans, ans1); 
	}
	cout << ans << "\n";
}
int main() {
	IOS;
	int t;
	cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}

D.Masha and a Beautiful Tree

题目链接:

Problem - D - Masha and a Beautiful Tree

题面:

在这里插入图片描述

题目大意:

已知一颗二叉树的叶子的数值,问能否对于任意节点,进行翻转叶子的操作,使得这颗树的叶子的数值,从左到右递增。

思路:

第一眼看到这题的时候我的第一反应是"woc,树上操作,不会不会"(bushi)。后面发现是题目中的图限制了我的思路,这题根本不需要运用树和图来解。
我们将叶子的值看成一个数组,对于这个数组,每相邻两个的值可以进行翻转,每相邻四个的值也可以进行翻转,每相邻8个的值也可以进行翻转…
那么我们运用递归的思想,对数组内每两个元素看成一组,求出每一组的最大值和最小值,然后对每两组进行最大值和最小值进行比较,如果左边的最小值介于右边的最大值和最小值之间或者右边的最小值介于左边的最小值和最大值之间,则不可能满足最终整个数组从左到右递增(不懂的画个图就很清楚,反正我是懂的(/doge))。之后便是对4,8,16,32…进行上述操作。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 3e5 + 10;
const ll mod = 1e11 + 3;
const double PI = acos(-1);
#define IOS std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
int a[MAX], b[MAX], c[MAX];
void solve() {
	int m;
	cin >> m;
	for (int i = 1; i <= m; i++) cin >> a[i];
	int n = m / 2;
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		if (a[i * 2 - 1] > a[i * 2]) ans++;
		b[i] = max(a[i * 2 - 1], a[i * 2]);
		c[i] = min(a[i * 2 - 1], a[i * 2]);
	}
	while (n > 1) {
		for (int i = 1; i < n; i += 2) {
			if ((c[i] > c[i + 1] && c[i] < b[i + 1]) || (c[i + 1] > c[i] && c[i + 1] < b[i])) {
				cout << "-1\n";
				return ;
			}
		}
		for (int i = 1; i <= n / 2; i++) {
			if (b[i * 2 - 1] > b[i * 2]) ans++;
			b[i] = max(b[i * 2 - 1], b[i * 2]);
			c[i] = min(c[i * 2 - 1], c[i * 2]);
		}
		n /= 2;
	}
	cout << ans << "\n";
}

int main() {
	IOS;
	int t;
	cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值