Codeforces Round #440 (Div. 2, based on Technocup 2018 Elimination Round 2)

本文精选了三道算法竞赛题目并提供了详细的解题思路及代码实现。第一题涉及数组匹配问题,第二题探讨如何合理分割数组以获得最优解,第三题则关注于合数分解的最优化方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 5e5 + 10;
const int INF = 1e9 + 10;
int n, m;
int a[qq], b[qq];

int main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}
	for(int j = 1; j <= m; ++j) {
		scanf("%d", b + j);
	}
	sort(a + 1, a + 1 + n);
	sort(b + 1, b + 1 + m);
	int minx = INF;
	for(int i = 1; i <= n; ++i) {
		for(int j = 1; j <= m; ++j) {
			if(a[i] == b[j]) {
				minx = min(minx, a[i]);
			}
		}
	}
	if(minx != INF) {
		printf("%d\n", minx);
		return 0;
	}
	if(a[1] == b[1]) {
		printf("%d\n", a[1]);
	} else {
		int x = a[1] * 10 + b[1];
		int y = a[1] + b[1] * 10;
		printf("%d\n", min(x, y));
	}
	return 0;
}


B

题意:把长度为n的分成k段,求每段中的最小值,然后要使得这个最小值最大

思路:k>=3的时候很显然我们可以让序列中的最大值自成一段,那么答案就是序列最大值,k = 1的时候答案是序列的最小值,k = 2的时候我们就做一下前缀和后缀,然后取其中的最大值即可

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 5e5 + 10;
const LL INF = 1e9 + 10;
int n, k;
int pre[qq], suf[qq];
int num[qq];

int main(){
	scanf("%d%d", &n, &k);
	int minx = INF;
	int maxn = -INF;
	for(int i = 1; i <= n; ++i) {
		scanf("%d", num + i);
		minx = min(minx, num[i]);
		maxn = max(maxn, num[i]);
	}
	if(n == 1) {
		printf("%d\n", num[1]);
		return 0;
	}
	if(k == 1) {
		printf("%d\n", minx);
		return 0;
	}
	if(k >= 3) {
		printf("%d\n", maxn);
		return 0;
	}
	for(int i = 1; i <= n; ++i) {
		if(i == 1)	pre[i] = num[i];
		else	pre[i] = min(pre[i - 1], num[i]);
	}
	for(int i = n; i >= 1; --i) {
		if(i == n)	suf[i] = num[i];
		else	suf[i] = min(suf[i + 1], num[i]);
	}
	maxn = -INF;
	for(int i = 2; i <= n; ++i) {
		maxn = max(maxn, max(pre[i - 1], suf[i]));
	}
	printf("%d\n", maxn);
	return 0;
}


C

题意:q次询问,给出一个数ni,求ni最多能分解成多少合数的和

思路:4 6 9可以组成任意一个合数,并且可以知道最多含一个6或者含一个9,对奇偶进行讨论即可

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 5e5 + 10;
const LL INF = 1e9 + 10;

int main(){
	int q;	scanf("%d", &q);
	while(q--) {
		int n;	scanf("%d", &n);
		if(n < 4) {
			puts("-1");
		} else {
			if(n & 1) {
				if(n < 9) {
					puts("-1");
				} else {
					int ans = 1;
					n -= 9;
					int tmp = n / 4;
					if(n == 2) {
						if(tmp == 0) {
							puts("-1");
						} else {
							printf("%d\n", tmp + ans);
						}
					} else {
						printf("%d\n", ans + tmp);
					}
				}
			} else {
				int tmp = n / 4;
				printf("%d\n", tmp);
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值