2021-08-01

Educational Codeforces Round 112 (Rated for Div. 2)

A.PizzaForces
题意:6个蛋糕一盒15元,8个蛋糕一盒20元,10个蛋糕一盒25元,给你一个整数n,如何花最少的价格能购买n个蛋糕。
思路:每种买法的蛋糕单价是一样的,所以只要保证买的蛋糕超过n越少越好,我们可以发现任意的大于等于6的偶数都可以被6,8, 10的整数倍表示。所以当n % 2== 0 && n >= 6答案就是单价乘以数量,当n % 2 == 1 && n > 6的时候,买的蛋糕总数超过n最小的值是1,所以这个时候先n ++再乘以单价。当然当n小于6的时候按照6买,花费最少。

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
LL n, ans;

int main()
{
	int t;
	cin >> t;
	while(t -- ){
		cin >> n;
		if(n < 6) ans = 15;
		else if(n % 2 == 0) ans = n * 5 / 2;
		else ans = (n + 1) * 5 / 2;
		cout << ans << endl;
	}
	return 0;
}

B.Two Tables
给你一个长为W,宽为H的区域S,里面有一个长方形A,长方形的左下坐标和右上坐标为(x1,y1),(x2,y2),再给你一个长为w,宽为h的小长方形B,问你将区域里面的长方形A最少移动多少单位,才能使小长方形放进区域且两个长方形没有重合区域,长方形的长要平行区域S的长,宽要平行区域S的宽,如果该区域不能同时放下这两个长方形,就输出“-1”。
思路:这道题其实只有上下移动或左右移动这两种情况,不存在斜着移动。
(1)假如你发现长方形B的长加上长方形A的长小于等于区域S 的长,那么你可以左右移动长方形A,
使长方形B能放进去,记录移动步数ans1。
(2)假如你发现长方形B的宽加上长方形A的宽小于等于区域S的 宽,那么你可以上下移动长方形A,使长方形B能放进去,记录移动步数ans2。
(3)如果 长方形B的长加上长方形A的长大于区域S 的长且长方形B的宽加上长方形A的宽大于区域S的宽,这种情况是不能同时放下两个长方形的,所以输出“-1”。
(4)答案就是(1)和(2)两个ans取个最小值。

代码:

#include <bits/stdc++.h>
// #define myl cout << "!!!!!!!" << endl;

using namespace std;

typedef long long LL;

double w, h, x1, x2, y1, y2, W,H;

void solve(){
	scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&W,&H,&x1,&y1,&x2,&y2,&w,&h);
	if((x2 - x1 + w > W) && (y2 - y1 + h > H)){
		printf("-1\n");
		return;
	}
	double ans1 = 1e10, ans2 = 1e10, ans = 1e10;
	if(h + y2 - y1 <= H){
		double cha;
		if(y1 >= H - y2){
			cha = y1;
		}else{
			cha = H - y2;
		}
		if(cha >= h){
			ans1 = 0;
		}else{
			ans1 =(double) (h - cha);
		}
	}
	if(w + x2 - x1 <= W){
		double cha;
		if(x1 >= W - x2){
			cha = x1;
		}else{
			cha = W - x2;
		}
		if(cha >= w){
			ans2 = 0;
		}else{
			ans2 =(double) (w - cha);
		}
	}
	if(ans1 < ans2) ans = ans1;
	else ans = ans2;
	printf("%.8lf\n",ans);
}
int main()
{
	int _ = 1;
	scanf("%d",&_);
	while(_ -- ){
		solve();
	}
	return 0;
}

C.Coin Rows
题意:给你一个2 * m的格子,每个格子上都有一个权值,Alice和Bob两个人玩游戏,从格子的左上端走到右下端,Alice先走,Bob后走。每个人走完后,得分为经过的地方的权值之和,且经过的地方权值变成0,Alice和Bob都希望自己的得分能高点,问你Bob的得分最少为多少。
思路:
在这里插入图片描述

假设红色是Alice走的,那么Bob会走经过A或者经过B的两条线路中每个格子上权值和最大的路。
所以这题只要枚举Alice走的路线的所有方式,然后依次将Bob选择路线上每个格子的权值和,取个最小值就行。要用前缀和优化。

代码:

#include <bits/stdc++.h>

using namespace std;

int m;
int a[100010];
int b[100010];
int suma[100010];
int sumb[100010];

int main()
{
	int t;
	cin >> t;
	while(t -- ){
		cin >> m;
		int sum = 2e9;
		int ans;
		memset(suma,0,sizeof(suma));
		memset(sumb,0,sizeof(sumb));
		for(int i = 1; i <= m; i ++ ) cin >> a[i];
		for(int j = 1; j <= m; j ++ ) cin >> b[j];
		suma[1] = a[1], sumb[1] = b[1];
		for(int i = 2; i <= m; i ++ ) suma[i] = suma[i - 1] + a[i];
		for(int i = 2; i <= m; i ++ ) sumb[i] = sumb[i - 1] + b[i];
		for(int i = 1; i <= m; i ++ ){
			ans= max(sumb[i - 1],suma[m] - suma[i]);
			sum = min(sum,ans);
		}
		cout << sum << endl;
	}
}

D. Say No to Palindromes
题意:我们称一种字符串是beautiful的,该字符串中不包含长度大于1的回文串。题目给你一个只包含a,b,c三个字母的回文串,给你m次询问,每次询问给你l,r,问你在区间[l,r]中,将里面的一些字母改成a,b,c使该区间是beautiful的,问你最少的改变次数是多少。
思路:
(1)一共只有三个字母,那么构成回文的字符串只有六种情况:

{'a','b','c'}, {'a', 'c', 'b'}, {'b', 'a', 'c'}, {'b', 'c', 'a'}, {'c', 'a', 'b'}, {'c', 'b', 'a'}}

(2)最少次数一定是这六种情况的一种,枚举这六种情况,取让整个字符串变成beautiful的改变次数是最小的就行。
(3)本题是交互题,要用前缀和优化,先求出整个字符串前i个需要改变的总次数是多少,然后每次问答既可以直接调用前缀和。
代码:

#include <bits/stdc++.h>

using namespace std;

char a[6][3] = {{'a','b','c'}, {'a', 'c', 'b'}, {'b', 'a', 'c'}, {'b', 'c', 'a'}, {'c', 'a', 'b'}, {'c', 'b', 'a'}};
int sum[6][200010];
char s[200010];

int n, m;
int main()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i ++ ) cin >> s[i];
	for(int i = 0; i < 6; i ++ ){ 		
		for(int j = 1; j <= n; j ++ ){
		sum[i][j] = sum[i][j - 1] + (s[j] != a[i][j % 3]);
		}
	}
	int l, r;
	while(m -- ){
		cin >> l >> r;
		int ans = r - l + 1;
		for(int i = 0; i < 6; i ++ ){
			ans = min(ans, sum[i][r] - sum[i][l - 1]);
		}
		cout << ans << endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值