首页 > 其他分享 >Codeforces Round #956 (Div. 2) C. Have Your Cake and Eat It Too

Codeforces Round #956 (Div. 2) C. Have Your Cake and Eat It Too

时间:2024-07-08 13:01:54浏览次数:17  
标签:cout la int s1 Codeforces 956 ra && Eat

Codeforces Round #956 (Div. 2)

C.Have Your Cake and Eat It Too

题目大意:

有长度为 n n n的数组 a , b , c a,b,c a,b,c,三个数组的和相同,把 n n n分为三段非空连续段 [ l a , r a ] , [ l b , r b ] , [ l c , r c ] [l_a,r_a],[l_b,r_b],[l_c,r_c] [la​,ra​],[lb​,rb​],[lc​,rc​],互不重合。
保证 ∑ i = l a r a a i , ∑ i = l b r b b i , ∑ i = l c r c c i > = k \sum_{i=l_a}^{r_a}a_i,\sum_{i=l_b}^{r_b}b_i,\sum_{i=l_c}^{r_c}c_i >=k ∑i=la​ra​​ai​,∑i=lb​rb​​bi​,∑i=lc​rc​​ci​>=k
k k k是大于等于 ∑ i = 1 n a i n \frac{\sum_{i=1}^{n}a_i}{n} n∑i=1n​ai​​的整数
输出 l a , r a , l b , r b , l c , r c l_a,r_a,l_b,r_b,l_c,r_c la​,ra​,lb​,rb​,lc​,rc​,如果无法分就输出-1

解题思路:

考虑三种可能性
1. [ l a , r a ] [l_a,r_a] [la​,ra​]在1-n左边,就是 a b c / a c b abc/acb abc/acb
2. [ l a , r a ] [l_a,r_a] [la​,ra​]在1-n右边,就是 b c a / c b a bca/cba bca/cba
3. [ l a , r a ] [l_a,r_a] [la​,ra​]在1-n中间,就是 b a c / c a b bac/cab bac/cab
先前缀和一遍,方便计算子数组的和
可能性1:
遍历 l a = 1 l_a=1 la​=1,遍历1-n,找到最小的 r a r_a ra​,然后在 [ r a + 1 , n ] [r_a+1,n] [ra​+1,n],遍历每个位置,判断一下 b b b和 c c c的子数组和是否满足 > = k >=k >=k

	for(int i=1;i<n-1;i++){
		if(a[i]>=k){
			s1=i;
			break;
		}
	}
	for(int i=s1+1;i<n;i++){
		if(b[i]-b[s1]>=k&&c[n]-c[i]>=k){
			cout<<1<<' '<<s1<<' '<<s1+1<<' '<<i<<' '<<i+1<<' '<<n<<'\n';
			return  ;
		}
		if(c[i]-c[s1]>=k&&b[n]-b[i]>=k){
			cout<<1<<' '<<s1<<' '<<i+1<<' '<<n<<' '<<s1+1<<' '<<i<<'\n';
			return  ;
		}
	}

可能性1:
遍历 r a = n r_a=n ra​=n,遍历n-1,找到最大的 l a l_a la​,然后在 [ 1 , l a − 1 ] [1,l_a-1] [1,la​−1],遍历每个位置,判断一下 b b b和 c c c的子数组和是否满足 > = k >=k >=k

	for(int i=n;i>2;i--){
		if(a[n]-a[i-1]>=k){
			s1=i;
			break;
		}
	}
	for(int i=1;i<s1-1;i++){
		if(b[i]>=k&&c[s1-1]-c[i]>=k){
			cout<<s1<<' '<<n<<' '<<1<<' '<<i<<' '<<i+1<<' '<<s1-1<<'\n';
		return ;
		}
		if(c[i]>=k&&b[s1-1]-b[i]>=k){
			cout<<s1<<' '<<n<<' '<<i+1<<' '<<s1-1<<' '<<1<<' '<<i<<'\n';
		return ;
		}
	}

可能性3:
遍历2-(n-1),枚举每个节点为 l a l_a la​,二分找满足条件的最小 r a r_a ra​,再判断两边的 b b b和 c c c的子数组和是否满足 > = k >=k >=k

	int s1,s2,s3,l,r,mid;
	for(int i=2;i<n;i++){
		l=i,r=n;
		while(l<r){
			mid=(l+r)/2;
			if(a[mid]-a[i-1]<k)l=mid+1;
			else r=mid;
		}
		if(a[l]-a[i-1]>=k){
			if(b[i-1]>=k&&c[n]-c[l]>=k){
				cout<<i<<' '<<l<<' '<<1<<' '<<i-1<<' '<<l+1<<' '<<n<<'\n';
				return ;
			}
			if(c[i-1]>=k&&b[n]-b[l]>=k){
				cout<<i<<' '<<l<<' '<<l+1<<' '<<n<<' '<<1<<' '<<i-1<<'\n';
				return ;
			}
		}
	}

最后都没有满足的就输出-1
完整代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=2e5+6;
int a[N],b[N],c[N];

void solve()
{
	int n,sum=0;
	cin>>n;
	a[0]=0,b[0]=0,c[0]=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]+=a[i-1];
		sum+=a[i];
	}
	for(int i=1;i<=n;i++){
		cin>>b[i];
		b[i]+=b[i-1];
	}
	for(int i=1;i<=n;i++){
		cin>>c[i];
		c[i]+=c[i-1];
	}
	int k=a[n]/3;
	if(a[n]%3)k++;
	int s1,s2,s3,l,r,mid;
	for(int i=2;i<n;i++){
		l=i,r=n;
		while(l<r){
			mid=(l+r)/2;
			if(a[mid]-a[i-1]<k)l=mid+1;
			else r=mid;
		}
		if(a[l]-a[i-1]>=k){
			if(b[i-1]>=k&&c[n]-c[l]>=k){
				cout<<i<<' '<<l<<' '<<1<<' '<<i-1<<' '<<l+1<<' '<<n<<'\n';
				return ;
			}
			if(c[i-1]>=k&&b[n]-b[l]>=k){
				cout<<i<<' '<<l<<' '<<l+1<<' '<<n<<' '<<1<<' '<<i-1<<'\n';
				return ;
			}
		}
	}
	for(int i=1;i<n-1;i++){
		if(a[i]>=k){
			s1=i;
			break;
		}
	}
	for(int i=s1+1;i<n;i++){
		if(b[i]-b[s1]>=k&&c[n]-c[i]>=k){
			cout<<1<<' '<<s1<<' '<<s1+1<<' '<<i<<' '<<i+1<<' '<<n<<'\n';
			return  ;
		}
		if(c[i]-c[s1]>=k&&b[n]-b[i]>=k){
			cout<<1<<' '<<s1<<' '<<i+1<<' '<<n<<' '<<s1+1<<' '<<i<<'\n';
			return  ;
		}
	}
	for(int i=n;i>2;i--){
		if(a[n]-a[i-1]>=k){
			s1=i;
			break;
		}
	}
	for(int i=1;i<s1-1;i++){
		if(b[i]>=k&&c[s1-1]-c[i]>=k){
			cout<<s1<<' '<<n<<' '<<1<<' '<<i<<' '<<i+1<<' '<<s1-1<<'\n';
		return ;
		}
		if(c[i]>=k&&b[s1-1]-b[i]>=k){
			cout<<s1<<' '<<n<<' '<<i+1<<' '<<s1-1<<' '<<1<<' '<<i<<'\n';
		return ;
		}
	}
	cout<<"-1\n";
}
signed main()
{

    int T;
    cin>>T;
    while(T--)
    {;
        solve();
    }
    return 0;
}

标签:cout,la,int,s1,Codeforces,956,ra,&&,Eat
From: https://blog.csdn.net/weixin_74313783/article/details/140262056

相关文章

  • 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\)的红......
  • Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)E-F
    E求一条树上的路径,使得走遍整棵树花费最小。我们容易发现树上的某条简单路径只需走一次,除此之外所有的路径都需要走两次,那么显而易见,我们需要求树的直径,之后将剩余的路径权值和乘二加上直径权值就可以。F数学题,对于数学题而言,个人感觉时间复杂度的计算对于题目的求解非常重......
  • Securing Large Language Models: Threats, Vulnerabilities and Responsible Practic
    本文是LLM系列文章,针对《SecuringLargeLanguageModels:Threats,VulnerabilitiesandResponsiblePractices》的翻译。保护大型语言模型:威胁、漏洞和负责任的做法摘要1引言2背景3LLM的安全和隐私问题4对抗性攻击和LLM漏洞5LLM的风险和失误6风险缓解策......
  • E. Kolya and Movie Theatre
    https://codeforces.com/problemset/problem/1862/E这题怎么说呢,有思路但是不够简洁这些我是想到了,但是考虑的因素太多,事实上只需要考虑加入/减去就可,然后记录sum如代码:#define_CRT_SECURE_NO_WARNINGS#include<iostream>#include<vector>#include<algorithm>#include<......
  • Educational Codeforces Round 167 (Rated for Div. 2)
    A容易发现由于玩家是八向移动,-1以及其上的硬币都可以接到,但是往下都无法。B子序列不需要连续,子串则必须连续,那么我们可以考虑对子串进行遍历,相当于遍历起点,求出子序列能和其对上的最大长度,然后用子串长度加上子序列的长度减去重合长度即可。C赛时C没D出的快,想贪心策略想......
  • Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)
    DensoCreateProgrammingContest2024(AtCoderBeginnerContest361)\(A\)Insert\(AC\)循环结构。点击查看代码inta[200];intmain(){intn,k,x,i;cin>>n>>k>>x;for(i=1;i<=n;i++){cin>>a[i];cout......