首页 > 其他分享 >Educational Codeforces Round 106

Educational Codeforces Round 106

时间:2022-12-31 22:55:46浏览次数:50  
标签:Educational 花费 线段 样例 Codeforces times cdot cdots 106

Educational Codeforces Round 106

前言

个人练习中的一场,做出了 A ~ D 题,为数不多的做出 div2 的 D 题的一次,于是来写个题解。

EF 题待补。


A. Domino on Windowsill

题目

有一个 \(2 \times n\) 的网格,第一行前 \(k_1\) 个网格被涂成了白色,第二行前 \(k_2\) 个网格被涂成了白色,其余网格为黑色。

现有 \(w\) 个白色多米诺骨牌(\(1\times 2\) 的矩形,可以旋转)和 \(b\) 个黑色多米诺骨牌,只能放在对应颜色的网格上,问是否能放置所有 \(w+b\) 个多米诺骨牌。

多组数据。

样例输入 #1

2
1 0 1
1 0
1 1 1
0 0

样例输出 #1

NO
YES

题解

不难发现,最多能放白色骨牌的数量就是 \(\lfloor \frac{k_1+k_2}{2} \rfloor\) ,黑色骨牌的数量是 \(\lfloor \frac{2n-k_1-k_2}{2} \rfloor\) ,判断 \(w\) 和 \(b\) 是否不超过最多数量即可。

void solve() {
	int n, k1, k2, w, b;
	
	cin >> n >> k1 >> k2 >> w >> b;
	
	int W = (k1 + k2) / 2, B = (2 * n - k1 - k2) / 2;
	
	cout << (w <= W && b <= B ? "YES" : "NO") << endl;
}

B. Binary Removals

题目

给定一个长度为 \(n\ (2\leq n \leq 100)\) 的只包含 \(0\) 和 \(1\) 的字符串,问是否能移去一些不相邻的字符,使得最终字符串为升序排列(即形成先 \(k_0\ (k_0\geq 0)\) 个 \(0\) ,再 \(k_1\ (k_1\geq 0)\) 个 \(1\) 的形式)。

多组数据。

样例输入 #1

5
10101011011
0000
11111
110
1100

样例输出 #1

YES
YES
YES
YES
NO

题解

观察到 \(n\) 的范围比较小,我们可以枚举前缀的长度 \(i\) ,判断是否能将 \(s[1\cdots i]\) 全变为 \(0\) ,以及是否能将 \(s[i+1\cdots n]\) 全变为 \(1\) 即可。

以判断是否能将 \(s[1\cdots i]\) 全变为 \(0\) 为例,要使其全变为 \(0\) ,需要移去这里面所有的 \(1\) ,所以只需判断有没有相邻的 \(1\) 即可。

void solve() {
	string s;
	cin >> s;
	
	int n = s.length();
	
	bool flag = false;
	rep(i, 0, n) {
	
		// remove all '1' of index 0 ~ i-1
		// remove all '0' of index i ~ n-1
		
		bool ok = true;
		rep(j, 0, i - 2) {
			if(s[j] == '1' && s[j + 1] == '1') {
				ok = false;
				break;
			}
		}
		
		rep(j, i, n - 2) {
			if(s[j] == '0' && s[j + 1] == '0'){
			    ok = false;
				break;
			}
		}
		
		if(ok){
			flag = true;
			break;
		}
	}
	
	cout << (flag ? "YES" : "NO") << endl;
}

C. Minimum Grid Path

题目

你要从 \((0,0)\) 走到 \((n,n)\) ,每次可以向上走或者向右走,只能最多转向 \(n-1\) 次。

设你转向了 \(k-1\) 次,形成了 \(k\) 条线段,现给定一个数组 \(c\) ,其中 \(c_i\) 代表第 \(i\) 条线段所需花费,最终的总花费为 \(\sum\limits_{i=1}^k c_i\times length_i\) ,其中 \(length_i\) 表示第 \(i\) 条线段的长度,求最小花费。

多组数据。

样例输入 #1

3
2
13 88
3
2 3 1
5
4 3 2 1 4

样例输出 #1

202
13
19

题解

不难发现向上走和向右走是独立的,我们规定第一步向右,那么 \(0,2,4,\cdots\) 等下标就为向右的花费,\(1,3,5,\cdots\) 等即为向上的花费。

我们枚举转弯的次数,计算不同方向上的最小花费,加起来就是当前步数对应的的花费,取最小值即可。

至于计算最小花费,如果在当前方向走了 \(x\) 条线段,那么一定是花费最小的那条线段长度为 \(n-(x-1)\) ,其余 \(x-1\) 条线段长度为 \(1\) 时该方向花费最小,花费为 \(\sum\limits_{i=1}^xc_{i}+(n-x)\times c_{min}\) ,其中 \(c_1,\cdots c_x\) 为这 \(n\) 条线段对应花费。

我们只需维护 \(c\) 的前缀和以及最小值,根据对应的 \(x\) 即可计算出当前步数对应的花费,时间复杂度 \(\mathcal{O}(n)\)。

void solve() {
    int n;
    cin >> n;
    	
    vector<i64> cost(n);
    for(auto &c : cost) cin >> c;

	int curX = 0, curY = 0;
    i64 minX = INF, minY = INF, ans = INF, sumX = 0, sumY = 0;
    	
    rep(i, 0, n-1) {    		
    	if(i % 2 == 0) {
    		curX++;
    		minX = min(minX, cost[i]);
    		sumX += cost[i];
    	}
    	if(i % 2 == 1) {
    		curY++;
    		minY = min(minY, cost[i]);
    		sumY += cost[i];
    	}
    		
    	if(i == 0) continue; // at least one turn
    		
    	i64 res = sumX + (n - curX) * minX +
			      sumY + (n - curY) * minY;

    	ans = min(ans, res);
    }
    	
    cout << ans << endl;
}

D. The Number of Pairs

题目

给定 \(c,d,x\ (1\leq c,d,x \leq 10^7)\),求有多少对正整数 \((a,b)\) 满足 $$c\cdot lcm(a,b) - d\cdot gcd(a,b) = x$$
其中 \(gcd(a,b)\) 表示 \(a\) 和 \(b\) 的最大公约数,\(lcm(a,b)\) 表示 \(a\) 和 \(b\) 的最小公倍数。

多组数据,\(t\ (1\leq t \leq 10^4)\) 为数据组数。

样例输入 #1

4
1 1 3
4 2 6
3 3 7
2 7 25

样例输出 #1

4
3
0
8

题解

令 \(g=gcd(a,b)\) ,\(a=Ag\) ,\(b=Bg\),其中 \(A\),\(B\) 互质。原等式变为:$$c\cdot ABg-d\cdot g=x$$
我们可以提取一个 \(g\),变为 $$g\cdot (cAB-d)=x$$
惯用套路,枚举 \(x\) 的约数 \(g\) ,可以算出 \(A\times B\) 的值为 \(\frac{x+d\cdot g}{c\cdot g}\),令其为 \(k\) ,可以发现 \(k\) 最大为 \(2\times 10^7\),问题转化为计算满足 \(gcd(n,m)=1\) 且 \(n\times m=k\) 的正整数数对个数。

将 \(k\) 分解质因数,可以发现 \(k\) 的每种质因子 \(p\) 只能同时全部给 \(n\) 或 \(m\) 其中一个,两种决策,乘法原理计算得答案为 \(2^{cnt}\) ,其中 \(cnt\) 是 \(k\) 的本质不同质因子个数。

发现这玩意是积性函数,所以可以线性筛,在 i % p[j] == 0 的时候会多算,减去 \(1\) 即可。

void sieve() {
	rep(i, 2, 2e7) {
		if(!vis[i]) p[++tot] = i, cnt[i] = 1;
		
		for(int j = 1; j <= tot && i * p[j] <= 2e7; j++) {
			vis[p[j] * i] = true;
			cnt[i * p[j]] = cnt[i] + 1;
			
			if(i % p[j] == 0) {
				cnt[i * p[j]]--;
				break;
			}
		}
	}
}

void solve() {
	i64 c, d, x;
	cin >> c >> d >> x;

	auto calc = [&](i64 k) -> i64 { // calculate the number of (n,m)
		return 1 << cnt[k];
	};

	vector<i64> fac;
	for(i64 g = 1; g <= x / g; g++) { // enumerate g
		if(x % g == 0) fac.pb(g);
		if(g != x / g) fac.pb(x / g);
	}

	i64 ans = 0;
	for(auto g : fac) 
		if((x + d * g) % (c * g) == 0)
			ans += calc((x + d * g) / (c * g));

	cout << ans << endl;
}

标签:Educational,花费,线段,样例,Codeforces,times,cdot,cdots,106
From: https://www.cnblogs.com/xhgua/p/EduR106.html

相关文章

  • Codeforces Good Bye 2022 CF 1770 A~E 题解
    题目链接A.KoxiaandWhiteboards注意每一步替换操作都是强制的,而不是可选的。所以就用一个multiset维护所有的数,每次选一个最小的替换掉即可。时间复杂度\(O(nlogn)\)......
  • Codeforces Round #765 (Div. 2)A,B,C
    CodeforcesRound#765(Div.2)A,B,C昨天晚上打了个牛客小白月赛,今天来补昨天的vp真是丢大脸了,竟然爆零了,我真是太菜了,o(╥﹏╥)oA这个A题老长了,说了半天的废话,看了半天都......
  • Codeforces Round #841 (Div. 2) and Divide by Zero 2022
    题目链接A核心思路:就是一个简单的找规律大胆去猜结论就好了。#include<iostream>#include<algorithm>usingnamespacestd;typedeflonglongLL;constintN=1e6......
  • Codeforces Good Bye 2022: 2023 is NEAR
    题目传送门:CodeforcesGoodBye2022:2023isNEAR。目录A.KoxiaandWhiteboardsA.KoxiaandWhiteboardsB.KoxiaandPermutationC.KoxiaandNumberTheoryD.Kox......
  • Codeforces Round #841 (Div. 2) and Divide by Zero 2022(A-D)
    CodeforcesRound#841(Div.2)andDividebyZero2022(A-D)题目链接限制AJoeyTakesMoneystandardinput/output1s,256MBBKillDemodogsstandard......
  • 12.30日 vp Codeforces Round #836 (Div. 2)
    A.SSeeeeiinnggDDoouubbllee题意:第一题题意很简单,即给出一个字符串,创造一个新字符串使得其是原字符串的两倍,且为一个回文串。思路:将原字符串倒置成为新字符串,然后接......
  • CodeForces 1349F1 Slime and Sequences (Easy Version)
    洛谷传送门CF传送门发现样例中所有数的和为\(n!n\),于是猜想好的序列总数为\(n!\)。考虑将每一个排列\(p\)唯一对应一个好的序列\(a\)。可以这么构造:在\(p\)中顺......
  • Codeforces 891 A. Pride 做题记录(DP)
    原题链接:https://codeforces.com/problemset/problem/891/A一个比较显然的性质是如果序列的总$gcd$不为$1$,那么肯定是不存在解的。因为不管怎么样,都有一个因子无......
  • Codeforces Round #838 (Div. 2) A-B,补C,D
    A.DivideandConquer题意:给定n个数,每次操作可以使得:$$\lfloor\frac{ai}{2}\rfloor$$,求最少的操作次数使得n个数的总和为偶数。分析:和为偶数,res=0和为奇数,暴力......
  • Codeforces 1253 C. Sweets Eating 做题记录(DP)
    很明显,贪心策略是先吃甜度大的可以保证最终的总甜度最小,因此我们先从小到大排个序。一天可以吃$m$个,因此我们对于每个$k$,就让甜度前$1~m$名在第一天吃,前$m+1~2m$名第二......