首页 > 其他分享 >Codeforces Round956(div2) A~C

Codeforces Round956(div2) A~C

时间:2024-07-09 13:59:12浏览次数:17  
标签:cur int Round956 void 矩阵 Codeforces tot num div2

A. Array Divisibility

题意:对于所有k = 1~n,能被j = 1~n 整除,要求以这些j作为下标a[j]的和也能够被k整除

思路:题目有点绕,但是仔细读懂题目其实会发现,其实就是从1到n按顺序输出一遍...,别被样例忽悠了

void solve(){
	int n;
	cin >> n;
	for(int i = 1;i<=n;i++){
		cout << i << " ";
	}
	cout << endl;
}

B. Corner Twist

题意:给定两个个n*m的矩阵填充0或1或2的a和b,进行数次操作,每次任选一个长宽不小于2的子矩阵,对于该子矩阵的两对对角而言,其中一对数值+1并mod3,另外一对+2并mod3,问能否将a变为b

思路:首先先将b矩阵每个值减去a矩阵每个值(小于0就加上一个模数),得到新矩阵c,此时问题转换为能否将一个均为0的n*m矩阵转换为该新矩阵c,观察对于每次操作,固定将两行和两列的值+3,因此对于c矩阵,判断每行每列的和是否mod3为0,是则可以转换,不是则不可以。代码如下:

void solve(){
	string a[505];
	string b[505];
	int c[505][505];
	int n,m;
	vector<int> h(n+5),w(m+5);
	cin >> n >> m;
	
	for(int i = 1;i<=n;i++)
			cin>>a[i];
	for(int i = 1;i<=n;i++){
		cin>>b[i];
		for(int j = 0;j<m;j++){
			int res = ((b[i][j]-'0') - (a[i][j]-'0'))<0?(b[i][j]-'0') - (a[i][j]-'0')+3:(b[i][j]-'0') - (a[i][j]-'0');
			c[i][j+1] = res;
		}
	}
	for(int i = 1;i<=n;i++)
		for(int j = 1;j<=m;j++)
			h[i] += c[i][j];
		
	for(int i = 1;i<=m;i++){
		for(int j = 1;j<=n;j++){
			w[i] += c[j][i];
		}
	}
	for(int i = 1;i<=n;i++){
		if(h[i]%3 != 0){
			cout << "NO" << endl;
			return;
		}
	}
	for(int i = 1;i<=m;i++){
		if(w[i]%3 != 0){
			cout << "NO" << endl;
			return;
		}
	}
	cout << "YES" << endl;
}

C. Have Your Cake and Eat It Too

题意:三个人选蛋糕,每个人按顺序选,选到的价值必须是总价值/3向上取整

思路:如果是两个人,那么要么第一个人先选要么第二个人先选,总共就两种情况,现在变成三个人,同理,最多有六种情况,进行分类讨论即可。

优化1:一种一种列出来可以,但是太长太耗时了,这次是6个,下次万一来更多个甚至更多咋办,所以我们可以用next_permutation函数进行排列。

函数介绍:bool next_permutation(iterator start,iterator end),当当前序列不存在下一个排列时,函数返回false,否则返回true,我们可以把a看作是0,b看作是1,c看作是2,作为数组索引方便写代码,代码如下:

void solve(){
	int n;  cin >> n;
	int tot = 0;
	vector<int> a[3];
	for(int i = 0;i<3;i++)
		for(int j = 1;j<=n;j++){
			int num;cin>>num;
			a[i].push_back(num);
			if(i == 0)
				tot+=num;
		}
	array<int,3> prem{0,1,2};
	do{
		int l[5];
		int r[5];
		int cur = 0;
		bool ok = true;
		for(int i = 0;i<3;i++){//按prem顺序依次选
			l[prem[i]] = cur;
			int sum = 0;
			for(int j = cur;j<n;j++){//找到大于tot/3上取整为止
				sum+=a[prem[i]][j];
				if(sum >= (tot+2)/3){//找到了 设置r
					r[prem[i]] = cur;
					cur+=1;
					break;
				}
				cur+=1;
			}
			if(sum < (tot+2)/3){//找不到 该种排列无解
				ok = false;
				break;
			}
		}
		if(ok){//有解 输出结果
			for(int i = 0;i<3;i++){
				cout << l[i]+1 << " "<<r[i]+1<< " ";
			}
			cout << endl;
			return;
		}
	}while(next_permutation(prem.begin(),prem.end()));
	cout << -1 << endl;//所有排列都无解  输出结果
}

 优化2:对于每个人查找价值大于tot/3上取整的过程,时间复杂度为O(n),这里可以用前缀和加二分进行优化,把时间复杂度降低到O(logn),代码如下:

void solve(){
	int n;  cin >> n;
	int tot = 0;
	vector<int> a[3];
	for(int i = 0;i<3;i++)
		for(int j = 0;j<n;j++){
			int num;cin>>num;
			int last = j-1<0?0:a[i][j-1];
			a[i].push_back(num+last);
			if(i == 0)
				tot+=num;
		}
	array<int,3> prem{0,1,2};
	do{
		int l[5];
		int r[5];
		int cur = 0;
		bool ok = true;
		
		for(int i = 0;i<3;i++){//按prem顺序依次选
			int solt = prem[i];
			l[solt] = cur;
			int tar = cur-1<0?(tot+2)/3:(tot+2)/3+a[solt][cur-1];
			auto it = lower_bound(a[solt].begin(),a[solt].end(),tar);//二分查找第一个大于等于tar的值
			if(it == a[solt].end()){//找不到
				ok = false;
				break;
			}else{//找到了
				r[solt] = it-a[solt].begin();
				cur = r[solt]+1;
			}	
		}
		if(ok){//有解 输出结果
			for(int i = 0;i<3;i++){
				cout << l[i]+1 << " "<<r[i]+1<< " ";
			}
			cout << endl;
			return;
		}
	}while(next_permutation(prem.begin(),prem.end()));
	cout << -1 << endl;//所有排列都无解  输出结果
}

标签:cur,int,Round956,void,矩阵,Codeforces,tot,num,div2
From: https://blog.csdn.net/weixin_46654188/article/details/140273194

相关文章

  • Codeforces Round 953(Div.2) 题解(A-E)
    CodeforcesRound953(Div.2)题解(A-E)A题意Alice有n本书,第一本书有\(a_1\)页,序号为1,第二本书有\(a_2\)页,序号为2,……,第n本书有\(a_n\)页,序号为n。Alice将把所有书分成两堆,并阅读每一堆中序号最大的一本书。Alice喜欢读书,请你告诉她,她最多可以读多少页的书。Solution第......
  • CodeForces CF1980C Sofia and the Lost Operations 题解 但是最后TLE 仅供思路参考
    CodeForcesCF1980CSofiaandtheLostOperations题解嗨嗨,又来了啊,蒟蒻再来一篇题解SofiaandtheLostOperations题面翻译索菲亚有一个包含$n$个整数的数组$a[1],a[2],…,a[n]$。有一天她对这个数组感到厌倦,于是决定顺序地对其应用$m$个修改操作。每个修改操作由一......
  • Codeforces Round #956 (Div. 2) C. Have Your Cake and Eat It Too
    CodeforcesRound#956(Div.2)C.HaveYourCakeandEatItToo题目大意:有长度为nnn的数组a......
  • Codeforces Round #956 (Div. 2) and ByteRace 2024
    CF1983A.ArrayDivisibility很快发现输出\(\mathbf{1\simn}\)符合题意。B.CornerTwist结论题。关键的充要条件是\(a,b\)的每一行/列的和模\(\mathbf{3}\)后相等。证明的话,首先要想到\(\mathbf{2\times2}\)的操作是可以完成所有大小的子矩阵操作的,手模一下可以发......
  • Codeforces Round 956 (Div. 2)
    A.ArrayDivisibilityArrayDivisibility直接输出1到n#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn;cin>>n;for(inti=1;i<=n;i++){cout<<i<<(i==n?'\n':'......
  • CodeForces CF1986C Update Queries题解
    来吧,兄弟们,再来篇题解,其实也不是题解,是我自己的思路/心得/体会UpdateQueries题面翻译题目翻译一共$t$组数据,每组数据给定长度为$n$的字符串$s$,长度为$m$的$ind$数组和字符串$c$。你可以任意安排$ind$数组和字符串$c$的顺序,并按照此顺序对字符串$s$进行$m$......
  • **CodeForces CF1928B Equalize题解**
    ok兄弟们,今天本蒟蒻来做一篇小小的题解Equalize题面翻译有一个给定的长度为$n$的数列$a$,现在加上一个排列$b$,即$c_i=a_i+b_i$。现在求对于所有可能的$b$,$c$中出现最多的数的出现次数的最大值。translateby@UniGravity.题目描述Vasyahastwohobbies—addingpe......
  • codeforces1849 D. Array Painting
    题目链接https://codeforces.com/problemset/problem/1849/D题意输入\(n(1\leqn\leq2e5)\)和长为\(n\)的数组\(a(0\leqa[i]\leq2)\)。最初,数组的每个元素都是蓝色的。有两种类型的操作:支付一枚硬币,选择一个蓝色元素,将其涂成红色。选择一个不等于\(0\)的红......
  • Educational Codeforces Round 167 (Rated for Div. 2)
    A容易发现由于玩家是八向移动,-1以及其上的硬币都可以接到,但是往下都无法。B子序列不需要连续,子串则必须连续,那么我们可以考虑对子串进行遍历,相当于遍历起点,求出子序列能和其对上的最大长度,然后用子串长度加上子序列的长度减去重合长度即可。C赛时C没D出的快,想贪心策略想......
  • Codeforces Round 951 (Div. 2)
    Preface这场由于下午四点约好了和祁神打乒乓球,因此两点开了一场VP,结果困得要死D题一个特判写挂了没看出来调了贼久然后E题秒出正解,但因为一个极其傻逼的地方挂了又没调出来,鉴定为纯纯的飞舞A.GuesstheMaximum签到,每次选的一定是相邻的两个#include<cstdio>#include<iost......