Educational Codeforces Round 127 (Rated for Div. 2) A - D

A. String Building

题意:给定字符串,判断是否能由aa,aaa,bb,bbb组成。

思路:其实我们可以发现,任何大于1的数都可以由2和3的组合组成。所以我们只需要判断是否存在单独的a或者单独的b就行了。说来惭愧,这题我刚开始考虑的太复杂了,导致Wrong了2发。呜呜呜,还是功力不太深厚啊。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
//const int N = 2e5 + 10;
//int q[N], cnt[N];
signed main() {
	int t;
	cin >> t;
	for(int i = 0; i < t; i++) {
		string s;
		cin >> s;
		char t = s[0], cnt = 0;
		for(int j = 0; j < s.size(); j++) {
			if(s[j] == t) cnt++;
			else {
				if(cnt < 2) {
					break;
				}
				t = s[j];
				cnt = 1;
			}
		}
		if(cnt < 2) puts("NO");
		else puts("YES");
	}
	return 0;
} 

B. Consecutive Points Segment

题意:给定n个数,每个数可以最多只进行一次操作(+1或者-1),判断能否通过这种操作,使得这个数组满足:

anam==nm(n>m)

也就是说元素之差等于距离之差。

思路:这样可以说是贪心吧?我的想法是: 对于一串连续的自然数,我们就把这一串数压缩,只用首尾两个数表示,最后将判断这些压缩的数对。但是有一点很重要:如果两个数相差大于3,那么就肯定是没救了。每个数对只能移动一次,我们用一个bool数组记录就好了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int>PII;
const int N = 2e5 + 10;
int q[N];
PII cnt[N];
bool st[N];
void solve() {
	int n;
	cin >> n;
	for(int i = 0; i < n; i++) cin >> q[i];
	int k = 0;
	for(int i = 0; i < n; i++) {
		int j;
		for(j = i + 1; j < n; j++) {
			if(q[i] + j - i != q[j]) break;
		}
		cnt[k].second = q[j-1];
		cnt[k].first = q[i];
		k++;
		i = j-1;
	}
	for(int i = 0; i < k; i++) st[i] = false;
	//for(int i = 0; i < k; i++) cout << cnt[i].first << ' ' << cnt[i].second << endl;
	for(int i = 1; i < k; i++) {
		if(cnt[i].first - cnt[i-1].second == 1) continue;
		else if(cnt[i].first - cnt[i-1].second == 2) {
			if(st[i-1]) {
				cnt[i].second -= 1;
				st[i] = true;
			}else {
				st[i] = true;
			}
		} else if(cnt[i].first - cnt[i-1].second == 3) {
			if(st[i-1]) {
				puts("NO");
				return;
			}
			cnt[i].second -= 1;
			st[i] = true;
		} else if(cnt[i].first - cnt[i-1].second > 3) {
			puts("NO");
			return;
		}
	}
	puts("YES");
 
}
signed main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
} 

C. Dolce Vita

题意:给定一个序列a[n](表示n袋糖果的价格,每个糖果每天只能买一次)和一个金额k,每天a[n]的所有元素都会+1,问至多能买多少袋糖果(如果某一天k有剩余,那么第二天不会用到前一天剩余的钱)。

思路:先排序求前缀和,然后依次求出第i袋糖果最多可以买到的天数,最后相加就行了。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
#define int long long
#define pb push_back
 
void solve() {
	int n, k;
	cin >> n >> k;
	vector<int>a;
	for(int i = 0; i < n; i++) {
		int x;
		cin >> x;
		a.pb(x);
	}
	sort(a.begin(), a.end());
	int ans = 0, sum = 0;
	for(int i = 0; i < a.size(); i++) {
		sum += a[i];
		if(sum <= k) {
			ans += (k - sum) / (i + 1) + 1;  // 求第i袋糖果可以买到的天数。
		} else break;  
	}
	cout << ans << endl;
}
signed main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
}

D. Insert a Progression

题意:给n个数,和一个数x,x表示有x个从1到x的自然数。将这x个自然数插入到这n个数中(可以是中间,可以是首尾)。求插入后的:|aiai+1|之和的最小值。

思路:分析,当要插入的值在a,b之间时,无论怎么插,结果都是b-a, 所以我们只需要判断这n个数的最大值mx和x的大小以及最小值mn和1的大小。当x大于mx的时候,我们可以把x插到头,此时增加的值为x - a[0], 插到尾时,增加的值为:x - a[n-1], 插到mx旁边时增加的值为:2 * (x - mx); 这里我推到一下为什么是2 * (x - mx)。 假设插到mx后面吧,并设mx后面跟着的数是ai。有:

... mx mx + 1 mx + 2... x ai, 此时增加的值为:xmx+xai(mxai)=2(xmx)

求这三者最小值即可,mn和1也是相同的思考方式。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int q[N];
//bool st[N];
//#define int long long
#define pb push_back
 
void solve() {
	int n, x;
	cin >> n >> x;
	int mx = 0, mn = N;
	for(int i = 0; i < n; i++) {
		cin >> q[i];
		mx = max(mx, q[i]);
		mn = min(mn, q[i]);
	}	
	long long ans = 0;
	for(int i = 0; i < n - 1; i++) ans += abs(q[i] - q[i+1]);
	if(x > mx) ans += min(abs(q[0] - x), min(abs(q[n-1] - x), 2 * (x - mx)));
	if(1 < mn) ans += min(abs(q[0] - 1), min(abs(q[n-1] - 1), 2 * (mn - 1)));
	cout << ans << endl;
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
}
posted @   飘向远方丶  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示