首页 > 其他分享 >Educational Codeforces Round 158 (Rated for Div. 2) A-C

Educational Codeforces Round 158 (Rated for Div. 2) A-C

时间:2023-11-25 09:01:16浏览次数:434  
标签:std Educational Rated int 158 单元格 typedef long t1

A

大致题意: 有一条长度为x的直线公路,最开始你位于0号点并且此时你的油箱装满了油,公路有n个加油站,当你经过加油站的时候你可以在加油站加满油,每走一个单位需要花费1升油量,起始位置和终点没有加油站,请问你的油箱容量至少为多少升才可以够你跑一个来回。

解题思路: 我们的路径大致是这样0 -> a[1] -> a[2] -> ... a[n] -> x - > a[n] -> ... a[2] -> a[1] -> 0,观察发现除了a[n] -> n - > a[n]的时候这两段路程走完之前没有加油站其他的时候都有加油站,所以只需要算出其他路径的差的最大值和2 * (n - a[n])取一个max就是答案。

#include <bits/stdc++.h>
 
#define ll long long
#define db double
typedef std::pair<int, int > PII;
typedef std::pair<int, std::pair<int, int>> PIII;
typedef std::pair<ll, ll> Pll;
typedef std::pair<double, double> PDD;
using ld = double long;
const long double eps = 1e-9;
int d1[] = {0, 0, 1, -1};
int d2[] = {1, -1, 0, 0};
const int N = 2e5 + 10, M = N << 1;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
#define ls u << 1
#define rs u << 1 | 1

int n, m, k;
int a[N];

int main(void){
   	std::ios::sync_with_stdio(false);
   	std::cin.tie(0);
   	std::cout.tie(0);
   	
   	int _ = 1;
   	
	std::cin >> _;
	while(_ --) {
		
		std::cin >> n >> m;
	
		for (int i = 1; i <= n; i ++) std::cin >> a[i];
		a[n + 1] = m;
		int mn = 0;
		
		for (int i = 1; i <= n; i ++) 
			mn = std::max(mn, a[i] - a[i - 1]);
		
		mn = std::max(mn, a[n + 1] - a[n] + a[n + 1] - a[n]);
		std::cout << mn << '\n';
		
	}

    return 0;
}

B

**大致题意: 有一个长度为n的单元格,每个单元格上都有一个整数,最开始都是0. 一开始芯片在第一个位置,每当一个回合结束时(最开始也视为一个回合),芯片所在的单元格的整数+1.每回合结束时我们都有两个操作: **
**操作1:将芯片移动到下一个单元格(例如,如果芯片在 i单元格,则将其移动到 i + 1单元格)。如果芯片在最后一格,则无法进行此操作; **
**操作2:选择任意一个 x单元格,将芯片传送到该单元格。可以选择芯片当前所在的单元格; **

每个单元格都有一个目标整数c[i]你的目标就是让每个单元格上的整数变为c[i],并且操作尽可能少的操作2,问最少使用多少次操作2可以让单元格上的整数都达成目标。

解题思路: 观察发现如果c[i] >= c[i + 1]那么每次使用操作2传送回 i 的时候能用操作1把格子i + 1也给走了。也就是说如果有这么一个连续子数组c[i] >= c[i + 1] >= c[i + 2] ...答案就是芯片传送回第i个格子的次数。可以将整个数组划分为若干段这样不上升的子数组。一旦c[i] < c[i + 1]就是新的一段的开始。需要注意的细节是我们在走c[i]的时候能把c[i + 1]也给走了,也就是新的一段需要减去上一段的最后一个元素。由于最开始就在第一个位置,所以需要将最开始的上一段置为1方便统计答案。

#include <bits/stdc++.h>
 
#define ll long long
#define db double
typedef std::pair<int, int > PII;
typedef std::pair<int, std::pair<int, int>> PIII;
typedef std::pair<ll, ll> Pll;
typedef std::pair<double, double> PDD;
using ld = double long;
const long double eps = 1e-9;
int d1[] = {0, 0, 1, -1};
int d2[] = {1, -1, 0, 0};
const int N = 2e5 + 10, M = N << 1;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
#define ls u << 1
#define rs u << 1 | 1

int n, m, k;
int a[N];

int main(void){
   	std::ios::sync_with_stdio(false);
   	std::cin.tie(0);
   	std::cout.tie(0);
   	
   	int _ = 1;
   	
	std::cin >> _;
	while(_ --) {
		
		std::cin >> n;
	
		for (int i = 1; i <= n; i ++) std::cin >> a[i];
		
		ll ans = 0;
		
		int i = 1, j = 2;
		int last = 1;
		for (; j <= n; j ++) {
			if (a[j] > a[j - 1]) {
				ans += a[i] - last;
				i = j;
				last = a[j - 1];
			}
		}
		ans += a[i] - last;
		
		std::cout << ans << '\n';
		
	}

    return 0;
}

C

大致题意: 有一个长度为n的数组,你可以进行无数次以下操作:将数组上每个数字加上x(0 <= x <= 1e18)然后除以2(下去整),问最少要多少次可以让数组所有元素相等。


解题思路: 我们关注两个元素t1, t2(t1 < t2)。

  如果t2 - t1 == 1的话我们只需要操作一次就可以得到答案:1.若t1为偶数:让t1和t2除以2一次就可以让他们两个一样。2.如果t1为奇数:需要先让t1和t2加上1再除以2就可以使他们两个一样。

  如果t2 - t1 > 1,就变成了如何让(t2 + x) / 2 - (t1 + x) / 2差值更小,此时会发现如果t1为奇数且t2为偶数那么x = 1会让差值更小(写题的时候只需要判断t1是否为奇数即可,就算t2也是奇数那么都加上1之后再除以2这两者的差值大小也是不会变的)。在这个过程中发现无论如何t2的不可能变的比t1小,t1不可能变的比t2大,所以只取数组中的最大值和最小值,只要它们两个变的一样了那么其他所有数字一定和他们两个一样。

#include <bits/stdc++.h>
 
#define ll long long
#define db double
typedef std::pair<int, int > PII;
typedef std::pair<int, std::pair<int, int>> PIII;
typedef std::pair<ll, ll> Pll;
typedef std::pair<double, double> PDD;
using ld = double long;
const long double eps = 1e-9;
int d1[] = {0, 0, 1, -1};
int d2[] = {1, -1, 0, 0};
const int N = 2e5 + 10, M = N << 1;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
#define ls u << 1
#define rs u << 1 | 1

int n, m, k;
int a[N];


int main(void){
   	std::ios::sync_with_stdio(false);
   	std::cin.tie(0);
   	std::cout.tie(0);
   	
   	int _ = 1;
   	
	std::cin >> _;
	while(_ --) {
		std::cin >> n;
	
		for (int i = 1; i <= n; i ++) std::cin >> a[i];
		
		std::sort(a + 1, a + n + 1);
		
		int mn = a[1], mx = a[n];
		
		int ans = 0;
		std::vector<int> tmp;
		while (mn < mx) {
			if (mx - mn == 1) {
				if (mn % 2 == 1) tmp.push_back(1);
				else tmp.push_back(0);
				break;
			}
			if (mn % 2 == 1) {
				mn = (mn + 1) / 2;
				mx = (mx + 1) / 2;
				tmp.push_back(1);
			} else {
				mn = mn / 2;
				mx = mx / 2;
				tmp.push_back(0);
			}
		}
			
		std::cout << tmp.size() << '\n';
		if (tmp.size() <= n && tmp.size()) {
			for (int i = 0; i < tmp.size(); i ++) std::cout << tmp[i] << ' ';
			std::cout << '\n';
		}
		
	}

    return 0;
}

D

大致题意:给你一个n个怪和n个怪的血量,你是一个强大的魔法师可以选择攻击任意一个怪对他造成x的伤害(只能释放一次),然后你的攻击会随机选择相邻的怪并对其造成x - 1的伤害,现在有两个怪被攻击了,接下来会随机选择攻击和这两个怪相邻的怪(每个怪只会被攻击一次)并造成x - 2的伤害,以此类推。一旦怪物受到的伤害大于等于它的血量他就会死掉,询问你最少需要使用多少伤害的魔法(x)才能将所有的怪杀死。请注意,你选择的是初始目标和法术威力,其他事情应视为随机,你希望即使在最坏的情况下也能杀死所有怪物。

标签:std,Educational,Rated,int,158,单元格,typedef,long,t1
From: https://www.cnblogs.com/qdhys/p/17855152.html

相关文章

  • 「杂题乱刷」CF1585B
    原题链接CF1585BArrayEversion题目简述现在有一个长度为\(n\)的序列\(a\),每次操作将\(a\)中不大于序列\(a\)中最后一个数的元素按照在\(a\)序列中的顺序放入\(b\)序列中,大于序列\(a\)中最后一个数的元素同样按照在\(a\)中的顺序放入\(c\)序列中,然后再将\(c......
  • CSE 158/258 设计与实现
    任务定于11月20日星期一完成,但请确保将解决方案上传到排行榜有规律地您应该提交两个文件:writeup.txt对每个任务的解决方案进行简要的纯文本描述;请在提交截止日期提前;这只是为了帮助我们遵循您的代码,不需要待详细说明。assignment1.py包含解决方案的工作代码的python文件。自动标......
  • Educational Codeforces Round 99 (Rated for Div. 2)
    https://codeforces.com/contest/1455很久没有vp了,感觉思维又僵化了A题直接看样例,直接猜是长度。B题首先如果是\(x=\frac{n(n+1)}{2}\),那么就是n否则如果\(x=\frac{n(n+1)}{2}+y\),分成两类y=n,ans=n+2,y<n,我们总可以找到前面一个替换,然后恰好的到n,选取z=n-y即可C题感觉比B......
  • Educational Codeforces Round 156 (Rated for Div. 2) ABCD
    EducationalCodeforcesRound156(RatedforDiv.2)ABCDA.SumofThree题意:给定正整数\(n\),判断是否存在正整数\(a\),\(b\),\(c\)满足:\(a+b+c=n\)。\(a\),\(b\),\(c\)均不是\(3\)的倍数。如存在,输出YES并构造一组方案,否则输出NO。思路:法一:我们分类讨论。根据......
  • Educational Codeforces Round 13 E
    tilian最开始看错了以为是可以任意选择两人or选择一人胜出但题意是可以选择下一个擂主是谁考虑dp的话我们显然需要记录一个state以及当前擂主是谁转移就是dp[state][i]=max(dp[state][i],dp[state(1<<j)][j]*a[i][j]+dp[state(1<<i)]*a[j][i])意义是我们枚举他后一个交......
  • Educational Codeforces Round 157 D
    tilian不太会这种题发现找到一个数就能确定整个序列然后转而发现前缀异或和b1^b2=a1b1^b3=a2...我们发现要是n为偶数时能直接求出b1从而确定整个序列而为奇数时我们无法确定b1我们思考拆位之后如果b1该位为0算出真实的异或后的01个数b1该位为1算出真实的......
  • Educational Codeforces Round 126 (Rated for Div. 2)
    https://codeforces.com/contest/1661/B题数据很小,直接bfs预处理就行C题随便猜了一下,设mx=\(max\{a_i\}\)最后的值应该是mx,mx+1,mx+2,mx+3之类的吧D题刚开始从前面考虑,陷入僵局,一度非常的困,学习凯库勒睡了一会,就突然想到了,前面不行,就从后面考虑,可以发现,从后面考虑的话,就非常......
  • [CF1588F] Jumping Through the Array
    不妨认为\(n,q\)同阶。考虑根号重构。如果没有第3种操作的话,我们每\(\mathcalO(\sqrtn)\)操作整体更新一次,每个询问只需要考虑块内的修改所在置换环上有多少\([l,r]\)内的数。这个是容易\(\mathcalO(n\sqrtn)\)做的。然后考虑置换环会变怎么办。注意到一个块内真......
  • cf1582F2. Korney Korneevich and XOR (hard version)(暴力优化)
    cf1582F2对于每种数可以维护一个列表v[x],表示到当前位置,最后一个数小于等于x,能够取到的值,对于当前的数ai,我们可以用v[ai]中的值x与ai异或,来更新v[ai+1],v[ai+2]后面的值。然后就是有两个优化,每次我们更新完后,都对v[a[i]]清空,因为只有两个相同数之间的数才对后面可能有贡献,前面的......
  • Educational Codeforces Round 157 (Rated for Div. 2)
    A.TreasureChest题目大意:人在0处,宝藏在x,钥匙在y,人最多拿宝箱z秒,问你最快多久开宝箱?思路:如果说钥匙在宝箱的左边,那么人只需要往右走就是最佳答案,如果钥匙在宝箱的右边,那么人只需要拿的宝箱到最佳地点就行#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ intx,y......