首页 > 其他分享 >Codeforces Round 954 (Div. 3)

Codeforces Round 954 (Div. 3)

时间:2024-06-24 13:53:50浏览次数:3  
标签:cur cin int 954 Codeforces 运算符 vector Div order

A. X Axis

题意:给3个x轴上的点xi,我们要放置一个点到x轴上,到这3个点的距离最短。(1 <= xi <= 10)

思路:直接暴力破解即可

int a, b, c;
inline int cal(int x){
	return abs(x - a) + abs(x - b) + abs(x - c);
}

void solve() {
	cin >> a >> b >> c;

	int ans = (int)1e9;
	for (int i = min({a, b, c}); i <= max({a, b, c}); ++i){
		ans = min(ans, cal(i));
	}
	cout << ans << '\n';
}

B. Matrix Stabilization

题意:给个n*m平面,可以进行无限次操作,对平面满足条件的点的数值进行修改。条件:与当前的格子共享了边的格子中,如果所有的格子的数值都比他小,则改变它为其他格子中的最大值。输出修改后的grid。

思路:修改没有后继性,一次遍历即可。

void solve() { 
	int n, m;
	cin >> n >> m;

	vector<vector<int>> mat(n + 1, vector<int> (m + 1));
	for (int i = 1; i <= n; ++i){
		for (int j = 1; j <= m; ++j){
			cin >> mat[i][j];
		}
	}

	for (int i = 1; i <= n; ++i){
		for (int j = 1; j <= m; ++j){
			int maxn = 0;
			for (int k = 0; k < 4; ++k){
				int pi = dx[k] + i;
				int pj = dy[k] + j;
				if (min(pi, pj) >= 1 && pi <= n && pj <= m){
					maxn = max(maxn, mat[pi][pj]);
				}
			}
			if (mat[i][j] > maxn){
				mat[i][j] = maxn;
			}
		}
	}

	for (int i = 1; i <= n; ++i){
		for (int j = 1; j <= m; ++j){
			cout << mat[i][j] << " \n"[j == m];
		}
	}
}

C. Update Queries

题意:给定长度为n的字符串s和长度为m的操作顺序ind和长度为m的字符串c。每次操作将s[idx[j]] = c[j]。但是现在可以对ind和(或)c进行重排序,目标是修改后的s字典序最小。输出s。

思路:贪心+sort。对操作去重并升序排序,对c升序排序,直接修改即可。

总结:一开始读错题了,以为对于相同的操作下标,可以更改其操作的顺序,使用的map,跑tc发现理解错题了,浪费几分钟。

void solve() { 
	int n, m;
	cin >> n >> m;

	string s;
	cin >> s;

	vector<int> order(m);
	for (int i = 0; i < m; ++i){
		cin >> order[i];
		order[i] --;
	}
	string c;
	cin >> c;

	sort(order.begin(), order.end());
	order.erase(unique(order.begin(), order.end()), order.end());

	sort(c.begin(), c.end());
	for (int i = 0; i < (int)order.size(); ++i){
		s[order[i]] = c[i];
	}

	cout << s << '\n';
}

后面开始,坐牢两个多小时...

D. Mathematical Problem

题意:给定长度为n的字符串,字符串包含0~9的数字。现在要为字符串加上exactly n - 2个运算符,运算符包括+和*。问加了运算符的表达式输出最少是多少。 (2 <= n <= 20)

思路:考虑n = 2的情况,不能加运算符,如果第一个字符为0,则输出第二个字符,否则输出s。
考虑n = 3且有0,0 在中间的情况,答案为第一个和第三个字符乘积或者相加中较小的一个。
其他长度的情况:如果有0,则将所有运算符置为乘,最后结果就是0。如果没有0,则将s中所有不为1的数统计求和。此时的求和有n - 1个运算符,其中涉及到1的运算符全为*,不涉及1的运算符全为+。此时需要去掉一个运算符,再次遍历s,依此考虑将s中任意两个相邻的字符组合成一个二位数字,看哪个组合最后得到的结果最小。

总结:一开始一眼dp(脑子抽了),然后就dp了一个多小时。。最后发现乘法的状态没办法转移,因为乘法会改变运算符顺序,还需要记录上一次加法的位置。。。太年轻了,居然想用dp,哎。
还有就是没看测试样例,其实看看测试样例就知道,要贪心的分情况讨论,看字符串中0和1,以及长度的情况。。
最后补题的时候,发现处理最后一种情况的写法很巧妙,先不将1加到贡献中,但是在缩减符号数量的时候,又必须考虑所有的1。 这种操作直觉上会让人想到在求sum的时候把x > 1的条件去掉,然后在求和的时候直接sum - s[i],但是这种会导致错误。为什么呢?因为有一些1最终不需要记录到答案中,而是作为乘法来消耗符号数量。

void solve() { 
	int n;
	cin >> n;

	string s;
	cin >> s;

	if (n == 2){
		cout << (s[0] == '0' ? string(1, s[1]) : s) << '\n';
	}
	else if (n == 3 && s[1] == '0'){
		cout << min(s[0] + s[2] - '0' * 2 , (s[0] - '0') * (s[2] - '0')) << '\n';
	}
	else if (s.find('0') != std::string::npos){
		cout << "0\n";
	}
	else{
		int sum = 0;
		for (const auto& x : s){
			if (x > '1') {
				sum += x - '0';
			}
		}
		int ans = INT_INF;
		for (int i = 0; i < n - 1; ++i){
			int num = stoi(s.substr(i, 2));
			ans = min(ans, sum - (s[i] == '1' ? 0 : s[i] - '0') - (s[i + 1] == '1' ? 0 : s[i + 1] - '0') + num);
		}
		cout << ans << '\n';
	}
}

E. Beautiful Array
题意:给定长度为n的数组a,现在可以将a shuffle,然后将a中的元素 + k(给的定值),最后a变成了一个回文数组,就是beautiful。 求最少的+k次数,或者输出-1(不可能完成)。

思路:首先map将a中的出现偶数次的元素去掉,然后如果一个数能通过另一个数相加若干个k得到,则这两个数%k的余数是相等的。然后将剩下的元素%k存到map<int, vector>中,最后遍历这个新的map,对vector排序,如果vector的元素数量是偶数,那么可以将相邻的两个vector作为一组进行+k变换。如果vector中的元素数量是奇数,那么这样的vector不能超过1个(奇数长度回文中心只有自己跟自己相等),然后维护一个前缀和后缀和来讨论vector中哪个元素作为回文中心,不参与到这种配对的计算中(自然是一个代价非常大的数,这里用前后缀和来维护非常巧妙,之前从来没有过这种想法)

总结:赛时在讨论vector为奇数时,实在是想不出来用什么方法来讨论出一个作为中心的元素,就这样耗到比赛结束,后面的题也没看。今天补提,发现使用前缀和后缀和,并将他们的求和的点放到同一个下标上,然后就可以奇妙的进行遍历,并且讨论了每个元素不参与计算的情况。

void solve() { 
	int n, k;
	cin >> n >> k;

	map<int, int> mapp;
	for (int i = 0; i < n; ++i){
		int t;
		cin >> t;
		mapp[t] ++;
	}

	vector<int> a;
	for (const auto&[x, y] : mapp){
		if (y & 1){
			a.push_back(x);
		}
	}

	if ((int)a.size() <= 1){
		cout << "0\n";
		return;
	}

	map<int, vector<int>> rec;
	for (int i = 0; i < (int)a.size(); ++i){
		int t = a[i];
		rec[t % k].push_back(t);
	}

	int cnt = 0;
	long long ans = 0;
	for (auto& [x, cur] : rec){
		bool ok = true;
		if (cur.size() & 1){
			cnt ++;
			ok = false;
			if (cnt > 1){
				cout << "-1\n";
				return;
			}
		}
		sort(cur.begin(), cur.end());
		if (ok){
			for (int i = 1; i < (int)cur.size(); i += 2){
				ans += (cur[i] - cur[i - 1]) / k;
			}
		}
		else if (cur.size() > 1){
			int m = (int)cur.size();
			vector<long long> pref(m);
			vector<long long> suff(m);
			pref[1] = cur[1] - cur[0];
			for (int i = 3; i < m; i += 2){
				pref[i] = pref[i - 2] + cur[i] - cur[i - 1];
			}
			suff[m - 2] = cur[m - 1] - cur[m - 2];
			for (int i = m - 4; i >= 0; i -= 2){
				suff[i] = suff[i + 2] + cur[i + 1] - cur[i];
			}
			long long minn = min(pref[m - 2], suff[1]);
			for (int i = 2; i < m - 2; i += 2){
				minn = min(minn, pref[i - 1] + suff[i + 1]);
			}
			ans += minn / k;
		}
	}

	cout << ans << '\n';

}

需要多思考,思维方面有点弱

有模板写题就是好用,只要维护固定的几个函数即可。
模板放在了下面的仓库,如果使用,请点进去点个star。
https://github.com/yxc-s/programming-template/tree/master
该仓库是一个新仓库,旨在打造一个通用的C++算法编程竞赛模板,包含数据结构,数论等各种实用的算法编程模板。如果您使用的语言不是C++,也可以将对应的代码实现翻译成其他语言来使用。

标签:cur,cin,int,954,Codeforces,运算符,vector,Div,order
From: https://www.cnblogs.com/yxcblogs/p/18264871

相关文章

  • 创新实训 (九)CodeForces 数据和微调数据处理
    Codeforces数据获取Codeforces的题目中存在一些数学公式,所以处理的时候需要比较小心的对其进行处理。首先是题面数据,在CF当中标识一道题目的方式是problemSet与problemId。其中problemSet是一个数字,而problemId是一个字母。另外需要注意的是CF题面中存在许多数学......
  • [题解]AT_agc054_b [AGC054B] Greedy Division
    思路首先不难发现一个规律,当\(sum\)为奇数时不可能有解。定义\(dp_{i,j,k,0/1}\)表示A在前\(i\)个数中选出和为\(j\)的\(k\)个数,且第\(i\)个不选/选的方案数。那么,我们只需要对于第\(i\)个数的状态分类讨论就能得到状态转移方程:不选\(i\),\(dp_{i,j,k,0}=......
  • [题解]AT_abc158_e [ABC158E] Divisible Substring
    思路首先发现一个事情,任意一个子串都可以由\(s\)的某一个后缀的后面删除一些字符得到。因此假如\(s\)的某一个后缀的值为\(x\),那么我们可以减去后面的我们不用的数字\(a\),然后除以\(10\)的若干次幂得到,即\(\frac{x-a}{10^n}\)。于是得到:\[\frac{x-a}{10^n}\equi......
  • 板刷codeforces构造题
    前言听说多写构造题可以提升思维能力...C.TurtleandanIncompleteSequence题目大意给定一个数组a,只有正整数和-1,-1可以改为正整数,问数组能否满足$\lfloora[i]/2\rfloor=a[i+1]或\lfloora[i+1]/2\rfloor=a[i]$,能则输出方案解题思路可以发现,相邻2个数在完全......
  • 山东菏泽家乡网页代码 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页
    ......
  • HTML旅游网页设计制作 DW旅游网站官网滚动网页 DIV旅游风景介绍网页设计与实现
    ......
  • Codeforces Round 952 (Div. 4)
    知识点模块1.一个正方体x,y,z里面可以放多少个边长为a,b,c的长方体ans=(x-a+1)*(y-b+1)*(z-c+1)题解模块A.CreatingWords交换两个字母的首字母即可swap实现即可点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>......
  • CF 1980 F1 Field Division (easy version) (*1900)
    CF1980F1FieldDivision(easyversion)(*1900)题目链接题意:有一个大小为\(n\timesm\)($2\len,m\le10^9$)的矩形。其中有\(k\)个喷泉,你现在可以从左侧或者上侧任意一个不是喷泉的单元格出发,每次只能移向相邻的下或者右的单元格。直到走到矩阵的右侧或者底侧结束。......
  • Codeforces Round 953 (Div. 2) A - F
    A编号为\(n\)的一定选,第二叠书在\(1\simn-1\)选最大的。voidsolve(){ cin>>n; for(inti=1;i<=n;++i){ cin>>a[i]; } intans=a[n]; intx=0; for(inti=1;i<n;++i){ x=max(x,a[i]); } cout<<ans+x<&......
  • Codeforces Round 953 Div.2 F 题解
    连通块计数的一种常见思路是钦定代表元,但发现这题的连边方式并不好指定一个代表元,那么只能尝试优化建图。我们尝试观察一下连边的情况,通过手玩样例获得一些几何直观的感受:345534453这个样例也许比较小,不过你真的把边画出来就会发现:连边形如\(2n-1\)条完整的斜线,中间......