Codeforces Round #388 (Div. 2)

本文解析了三道算法题:如何用最少的素数之和表示一个整数;根据三个顶点坐标推算平行四边形的第四个顶点;模拟竞赛中淘汰对手的过程来决定胜者。

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

A

题意:将一个数分成尽可能多的素数和  很显然 只需要2 和 3这两个素数就可以组成任何数的和

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

typedef long long ll;
const int qq = 1e5 + 10;
ll num[qq];
ll n, m, k;

int main(){
	cin >> n;
	if(n%2 == 0){
		cout << n/2 << endl;
		for(int i = 0; i < n/2 ;++i)
			cout << 2 << " ";
		cout << endl;
	}else{
		n -= 3;
		cout << 1+n/2 << endl;
		for(int i = 0; i < n/2; ++i)
			cout << 2 << " ";
		cout << 3 << endl;
	}
	return 0;
}

B

题意:给出一个平行四边行的三个顶点坐标, 求剩下一个

思路:对坐标派一个序, 然后求出偏移量 处理一下就行

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

typedef long long ll;
const int qq = 1e5 + 10;
ll num[qq];
ll k;
struct Point{
	int x, y;
}point[10], ans[qq];

void f(int len, int a, int b){
	for(int i = -1000; i <= 1000; ++i)
		for(int j = -1000; j <= 1000; ++j)
			if(len == abs(i-point[a].x)*abs(i-point[a].x)+abs(j-point[a].y)*abs(j-point[a].y) && len == abs(i-point[b].x)*abs(i-point[b].x)+abs(j-point[b].y)*abs(j-point[b].y)){
				ans[k].x = i, ans[k].y = j;
				k++;
				return;
			}
}
bool cmp(const Point &a,const Point &b) {
	if(a.x!=b.x) return a.x<b.x;
	else return a.y<b.y;
}
int main() {
	for(int i=0 ;i<3; i++) cin >> point[i].x >> point[i].y;
	sort(point,point+3,cmp);
	cout << 3 << endl;
	int xx = point[1].x-point[0].x;
	int yy = point[1].y-point[0].y;
	cout << point[2].x-xx << " " << point[2].y-yy << endl;
	cout << point[2].x+xx << " " << point[2].y+yy << endl;
	xx = point[2].x-point[1].x;
	yy = point[2].y-point[1].y;
	cout << point[0].x-xx << " " << point[0].y-yy << endl;
	return 0;
}

C

题意:n个人 分成两派, 问最后那一派获得胜利, 规则是这样的, 首先从1遍历到n 如果出现D, 那么他可以什么都不做, 也可以让某一个R退出比赛, 一轮过后假设还剩k个人 , 继续从1遍历到k.

思路:很显然要采取贪心的策略, 如果是D那么他肯定会使他右边离他最近的R推出比赛, 这样才能达到最策略, 右边没有了 则从最左边开始取.直接模拟了

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

typedef long long ll;
const int qq = 2e5 + 10;
ll num[qq];
int n;
string str;

int main(){
	cin >> n;
    cin >> str;
	int a =0, b = 0;
	while(1){
		for(int i = 0; i < n; ++i)
			if(str[i] == 'D'){
				if(b > 0)	str[i] = '.', b--;
				else	a++;
			}else if(str[i] == 'R'){
				if(a > 0)	str[i] = '.', a--;
				else	b++;
			}
		if(a || b){
			for(int i = 0; i < n; ++i)
				if(str[i] == 'D'){
					if(b > 0)	str[i] = '.', b--;
				}else if(str[i] == 'R'){
					if(a > 0)	str[i] = '.', a--;
				}
            if(a || b){
                if(a)   cout << "D" << endl;
                else    cout << "R" << endl;
                break;
            }
		}
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值