Codeforces Round 962 (Div. 3)(A~E)

题目链接:https://codeforces.com/contest/1996

写在前面

这场div.3难度比以前更大一些,一道C题想了半天都想不出来,导致这场比赛直接寄了·····,打的非常烂(不如直接摆烂睡觉:(

A-Legs

思路

考点:贪心
签到题,为了使动物尽可能小,**先考虑牛在考虑鸡(坤)**即可

编程

void solve(){
	int n;cin >> n;
	int ans=n/4;
	n%=4;
	ans+=n/2;
	cout << ans << endl;
	return ;
}

B-Scale

思路

题目最关键的一行:
在这里插入图片描述
由此可知,题目保证划分好的区域内的值相等,我们每次只需要取每个区域内第一个值就行

编程

void solve(){
	int n,k;cin >> n >> k;
	for(int i=1;i<=n;++i)
	   for(int j=1;j<=n;++j)
	     cin >> a[i][j];
	for(int i=1;i<=n;i+=k){
		for(int j=1;j<=n;j+=k){
			cout << a[i][j];
		}
		cout << endl;
	}
	return ;
}

C- Sort

思路

考点:模拟+前缀和
如果我们每次询问都进行暴力模拟,那必然会超时
因此,对于这题我们可以考虑用前缀和,在询问之前进行预处理
对于区间l,r的最小操作就是区间不同数的一半,在最后我们需要将答案除以2即可

编程

const int N=2e5+5;
int a[N][27],b[N][27];
void solve(){
	int n,q;
	cin >> n >> q;
	string s,t;
	cin >> s >> t;
	s = " "+ s;
	t= " " + t;
	for(int i=1;i<=n;++i){
		for(int j=0;j<26;++j){
			a[i][j]=a[i-1][j];
			b[i][j]=b[i-1][j];
		}
		++a[i][s[i]-'a'];
		++b[i][t[i]-'a'];		
	}
	while(q--){
		int l,r;
		cin >> l >> r;
		int ans=0;
		for(int j=0;j<26;++j){
			ans+=abs((a[r][j]-a[l-1][j])-(b[r][j]-b[l-1][j]));
		}
		cout << ans/2 << endl;
	}
	return ;
}

D-Fun

思路

考点:数学思维
对于a,b,c三个数,我们先考虑a的范围
对于 a b + a c + b c ≤ n ab+ac+bc≤n ab+ac+bcn 这个式子,我们令 b=1,c=1,这个式子近似于 a + a ≤ n a+a≤n a+an,因此a的取值范围在 [ 1 , n / 2 ] [1,n/2] [1,n/2]
然后我们在考虑b的范围,假设c=0, a ∗ b ≤ n a*b≤n abn,因此b的范围为 [ 1 , n / a ) [1,n/a) [1,n/a)
对于c,如果我们在套一层循环可能会超时,观察式子,循环中每次算出来的c都是最大值
因此c的取值范围在1~max,我们只需要将答案加上max即可
由于c需要满足两个条件,一个是 a b + a c + b c ≤ n ab+ac+bc≤n ab+ac+bcn转换一下为 c ≤ ( n − a ∗ b ) / ( a + b ) c≤(n-a*b)/(a+b) c(nab)/(a+b)
另一个是 c ≤ x − a − b c≤x-a-b cxab ,数学中两个小于号取其中最小的那个数
到此本题就出来了

编程

void solve(){
	int n,x;
	cin >> n >> x;
	int ans=0;
	for(int a=1;a<=n/2;++a)
	   for(int b=1;b<n/a;++b){
	   	if(a*b>=n) break;
	   	 if(x-a-b<0) break; 	 
	   	 ans+=min(x-a-b,(n-a*b)/(a+b));
	   }
	cout << ans << endl;
	return ;
}

E-Decode

思路

对于一段区间 [ l , r ] [l,r] [l,r],如果区间内0和1的个数相等那么这个区间对会使答案加 l ∗ ( n − r + 1 ) l*(n-r+1) l(nr+1)
问题就转移成怎么快速求出所有有效区间的位置
这里可以维护一个当前值now,遇到0减一,遇到1加一
如果一个区间1和0的数量相同的话,那么这个区间 [ l , r ] [l,r] [l,r] [ l − 1 , r ] 、 [ l − 2 , r ] 、 [ l , r + 1 ] 、 [ l , r + 2 ] [l-1,r]、[l-2,r]、[l,r+1]、[l,r+2] [l1,r][l2,r][l,r+1][l,r+2]··· 都是相同的
可以开一个map来记录每一个i的当前值对应的左部分的和对于位置为i对答案的贡献就是 m [ n o w ] ∗ ( n − i + 1 ) m[now]*(n-i+1) m[now](ni+1)

编程

void solve(){
	string s;cin >> s;
	int n=s.size();
	s= " " + s;
	unordered_map<int,int> m;
	int now=0,ans=0;
	m[0]=1;
	for(int i=1;i<=n;++i){
		if(s[i]=='0') now--;
		else now++;
		ans+=m[now]*(n-i+1);
		ans%=mod;
		m[now]+=i+1;//加i即加上左部分的和,加1为了后面遇到相同的now,先加上1
	}
	cout << ans << endl;
	return ;
}
  • 15
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值