首页 > 其他分享 >Codeforces Round 917 (Div. 2)

Codeforces Round 917 (Div. 2)

时间:2023-12-28 21:12:10浏览次数:32  
标签:int void Codeforces cin ++ ans 917 清零 Div

A. Least Product

  • 存在 \(a[i] = 0\),\(min = 0\),不需要任何操作。
  • 负数个数为偶数(包括0),\(min = 0\),把任意一个改为 \(0\)。
  • 负数个数为奇数,\(min = \prod a[i]\),不需要任何操作。
void solve() {
	int n;
	cin >> n;
	vector<int> b, c, d;
	for(int i = 0; i < n; ++ i) {
		int x;
		cin >> x;
		if(x > 0) b.push_back(x);
		else if(x == 0) c.push_back(x);
		else d.push_back(x);
	}
	if(c.size()) puts("0");
	else if(d.size() % 2 == 0) puts("1\n1 0");
	else puts("0");
}

B. Erase First or Second Letter

枚举每个字符 \(s[i]\),统计以当前字符为第一个元素的方案数。
因为第一个元素已经确定,所以只能删 \([i + 1, j]\)的子串。
先前出现过的字符直接 \(continue\)。

void solve() {
	int n;
	string s;
	cin >> n >> s;
	ll ans = 0;
	vector<bool> vis(26, 0);
	for(int i = 0; i < n; ++ i) {
		if(!vis[s[i] - 'a']) {
			vis[s[i] - 'a'] = 1;
			ans += (n - i);
		}
	}
	cout << ans << '\n';
}

C. Watering an Array

考虑把数组清零后怎么贪。
在若干次操作后,整个数组一定是非增的,因此每一天最多有一个位置满足条件。
显然,每两天就进行一次 \(reset\) 操作为最优。


现在回过来处理原始数组。
枚举操作到第 \(i\) 天后再清零。
一次清零最多能得到 \(n\) 个贡献。
因此当 \(i > 2n\) 后,一定不如一开始就清零更优,\(i\) 枚举到 \(2n\) 就行。
注意 \(i\) 要严格小于 \(d\),否则没有多余天数给清零操作。

void solve() {
	int n, k, d;
	cin >> n >> k >> d;
	vector<int> a(n + 1), v(k);
	int ans = 0;
	for(int i = 1; i <= n; ++ i) {
		cin >> a[i];
		if(a[i] == i) ++ ans;
	}
	for(int &x : v) cin >> x;
	ans += (d - 1) >> 1;
	for(int i = 0; i < 2 * n; ++ i) {
		if(i == d - 1) break;
		int res = 0;
		for(int j = 1; j <= v[i % k]; ++ j) ++ a[j];
		for(int j = 1; j <= n; ++ j) if(a[j] == j) ++ res;
		res += (d - i - 2) >> 1;
		ans = max(ans, res);
	}
	cout << ans << '\n';
} 

D. Yet Another Inversions Problem

E. Construct Matrix

一个显然的性质:若得到一组关于 \(k\) 的解,则对答案整个取反后能得到 \(k = n^2 - k\) 的解。
首先考虑无解。

  • 若 \(k\) 为奇数,无解。
  • 若 \(n > 2\) 且 \(k = 2\) 或 \(k = n ^2 - 2\),无解。

我们不妨假设剩下的情况都是有解的。
情况一:\(n=k\),很好构造。

void case1() {	// k == n
	for(int i = 1; i <= n; ++ i) a[i][i] = 1; 
}

情况二:\(n\bmod 4 = 0\)

  • 在一行(列)里添加偶数个 \(1\) 不会对原异或值有任何改动。

根据这条性质,容易想到用 \(\frac{k}{4}\) 个 \(2\times 2\) 的单元去填整个网格。

\[\left[ \begin{matrix} 1 & 1\\ 1 & 1 \end{matrix} \right] \]

void case2() {	// k % 4 == 0
	for(int i = 1; i <= n; ++ i) {
		for(int j = 1; j <= n; ++ j) {
			if(!a[i][j] && k) {
				a[i][j] = a[i + 1][j] = a[i][j + 1] = a[i + 1][j + 1] = 1;
				k -= 4;
			}
		}
	}
}

情况三:\(n\bmod 4 = 2\)
去思考如何把情况三转化到情况二。
我们可以在网格的左上角构造如下 \(4\times 4\) 的单元格。

\[\left[ \begin{matrix} 1 & 1 & 0 & 0\\ 1 & 0 & 1 & 0\\ 0 & 1 & 1 & 0\\ 0 & 0 & 0 & 0 \end{matrix} \right] \]

把 \(k\) 整体减去 \(6\) 后成功转化为情况二。
按照上述构造方法需要考虑 \(k_{max} = n^2 - 9\)。
如果 \(k\) 大于其最大值,则令 \(k = n^2 - k\),最后翻转答案。

void Reverse (){
	for(int i = 1; i <= n; ++ i)
		for(int j = 1; j <= n; ++ j)
			a[i][j] ^= 1;
}
void case3() { // k % 4 == 2
	
	bool f = 0;
	if(k > n * n - 10) f = 1, k = n * n - k;
	
	a[1][1] = a[1][2] = a[2][1] = a[2][3] = a[3][2] = a[3][3] = 1; 
	k -= 6;
	
	for(int i = 1; i <= n; ++ i) {
		for(int j = 1; j <= n; ++ j) {
			if(i <= 4 && j <= 4) continue;
			if(!a[i][j] && k) {
				a[i][j] = a[i + 1][j] = a[i][j + 1] = a[i + 1][j + 1] = 1;
				k -= 4;
			}
		}
	}
	if(f) Reverse();
}

F. Construct Tree

  • 对于任意两条边 \(e1,e2\),一定存在至少一条路径同时通过这两条边。
int n, d, a[N];
bitset<N> dp[N];

void solve() {
	cin >> n >> d;
	for(int i = 1; i <= n; ++ i) cin >> a[i];
	sort(a + 1, a + n + 1);
	if(a[n] + a[n - 1] > d) {
		puts("No");
		return;
	}
	for(int i = 0; i <= d; ++ i) dp[i].reset();
	dp[0][0] = 1;
	for(int i = 1; i < n; ++ i) {
		for(int j = d; j >= 0; -- j) {
			if(j + a[i] <= d) dp[j + a[i]] |= dp[j];
			dp[j] |= dp[j] << a[i];
		}
	}
	bool ok = dp[0][d - a[n]];
	for(int i = a[n]; i <= d - a[n]; ++ i) ok |= dp[i][d - i];
	puts(ok ? "Yes" : "No");
}

标签:int,void,Codeforces,cin,++,ans,917,清零,Div
From: https://www.cnblogs.com/Luxinze/p/17931070.html

相关文章

  • [Codeforces] CF1536C Diluc and Kaeya
    CF1536CDilucandKaeya题意题目传送门给你一个字符串\(S\),其中只包含'K'或'D'两种字符,要求划分这个字符串使得各部分的\(n(D):n(K)\)相同,其中\(n(D)\)表示\(S\)中字符'D'出现的个数,最大化划分后形成的组数。求出\(S\)的所有前缀中的上述答案。思路注意到,如......
  • codeforces刷题(1100):1901B_div2
    B、ChipandRibbon跳转原题点击此:该题地址1、题目大意  存在一条由n个单元格组成的带子。chip可以做两个操作:1、由\(i\)走到\(i+1\),但是不能走到\(i-1\);2、可以传送到任意位置,包括传送到原地。每到一个单元格,该单元格的数值+1(初始为0)。最开始chip在从第一格开始走起(题......
  • codeforces刷题(1100):1902B_div2
    B、GettingPoints跳转原题点击此:该题地址1、题目大意  Monocarp为了完成总共n天的某学期的p学分任务。Monocarp每天可以选择两种度过方式:上一次课和完成最多两个任务或者休息一天。其中上课获得l学分,每个任务获得t学分,其中任务不可以重复接取,并且每周获得一个新的任务(第一......
  • 实现div元素滚动条自动滚动到最底部(或最顶部)
    css属性 Overflow可以实现溢出显示滚动条overflow:scroll;或overflow-y:autooverflow-x:auto 实现div元素滚动条默认滚动到最底端使用场景:聊天信息框需要了解几个属性和方法:scrollHeight:元素高度(包含滚动条隐藏部分)clientHeight:元素可视高度(不包含滚动......
  • 【CF1917F】Construct Tree
    题目题目链接:https://codeforces.com/contest/1917/problem/F给出\(n\)条边的边权,询问是否可以构造出一棵树,使得所有边都被用上恰好一次且直径为\(d\)。\(n,d\leq2000\)。思路首先肯定是找出一条长度为\(d\)的链,然后判断可不可以把剩下的所有边都挂在这条链的带权重心......
  • Pinely Round 3 (Div. 1 + Div. 2)
    A.DistinctButtons#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ intn; cin>>n; inta=0,b=0,c=0,d=0; for(inti=1;i<=n;i++){ intx,y; cin>>x>>y; if(x>0)a=1; if(y>0)b=1; if(x<0)c=1; if(y<......
  • 「题解」Codeforces 1427G One Billion Shades of Grey
    感谢127的指导/ll\(|h_u-h_v|=\max(0,h_u-h_v)+\max(0,h_v-h_u)\),那么可以把它看成这样的问题:\[\min\{\sum_{(u,v)}\max(0,h_u-h_v+w_{u,v})c_{u,v}\}\]对偶一下,问题就变为:如果两个格子相邻就互相连容量为\(c_{u,v}=1\),费用为\(w_{u,v}=0\)的边,跑最大费用循环流。为了限......
  • 记一次el-checkbox包裹一层div,点击div勾选复选框,点击复选框却没反应的bug
    <divclass="account-item"v-for="iteminaccountList":key="item.id":class="[{'is-select-mode':isSelectMode},{'is-select':item.isSelect}]"@click="selectItem......
  • codeforces刷题(1100):1904B_div2
    B、CollectingGame跳转原题点击此:该题地址1、题目大意  获得一个由n位正整数组成的数组。你可以选择选择任意一个数作为你的判断值。然后任意一个\(\le\)它的数可以被选中加入你的分数(注意判断值不算在里面),同时该数被移除数组。你的任务是,对于该数组中的每个数,都将其作为......
  • codeforces刷题(1100):1905B_div2
    B、Begginer'sZelda跳转原题点击此:此题地址1、题目大意  给你一个子树,你可任意选择两个节点\(u、v\),这两个节点之间的所有节点(包括\(u、v\))都将结合变为一个新的节点。要求你通过该操作将所有的节点变为只有一个节点,求最小的操作数。2、题目解析  由题意可得:当\(u、v\)......