首页 > 其他分享 >牛客练习赛108-B

牛客练习赛108-B

时间:2023-02-17 23:35:19浏览次数:55  
标签:传递 练习赛 int ll loc2 牛客 108 loc1 d2

原题描述:链接:https://ac.nowcoder.com/acm/contest/51208/B
原题题解:链接:https://ac.nowcoder.com/discuss/1121134
题意:给出长度为n的正整数序列a, b,可以选择相邻的两个数传递2,问最少传递多少次使得两个正整数序列对应位置相等,如果无法使其相等输出-1
分析:当\(a[i]\equiv b[i](mod\) \(2)\)并且\(\sum_{i=1}^n a_{i}= \sum_{i=1}^nb_i\)时,才能有解
感性地说:对于i这个位置来说,如果序列a左边的数字之和(包含i这个数字)的比b的大,那么说明a序列需要从i到i+1传递两者相差的数值,比b小就是说明b序列从i到i+1传递两者相差的数值或者是考虑成i+1到i需要传递两者相差的数值
正式地说:见牛客原题题解
总结:对于这种需要一个一个位置传递算贡献的题,考虑当前位置与相邻的位置的传递对答案的贡献,然后加在一起即可

正解AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//-----------------------
void solve()
{
	int n;
	cin>>n;
	vector<ll> a(n+1), b(n+1);
	for(int i=1; i<=n; i++)cin>>a[i];
	for(int i=1; i<=n; i++)cin>>b[i];
	ll ans=0;
	for(int i=1; i<=n; i++){
		if(a[i]%2!=b[i]%2){
			cout<<-1<<'\n';
			return;
		}
		a[i]+=a[i-1];
		b[i]+=b[i-1];
		ans+=(max(a[i], b[i])-min(a[i], b[i]))/2;
	}
	if(a[n]!=b[n]){
		cout<<-1<<'\n';
	}else{
		cout<<ans<<'\n';
	}
}
int main(void)
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T=1;cin>>T;
	while(T--)solve();
	return 0;
} 
思路不清的双指针AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
//----------------------
void solve()
{
	int n;
	cin>>n;
	vector<int> a(n), b(n);
	ll d1=0, d2=0;
	vector<P> buc1, buc2;
	for(auto &v:a)cin>>v;
	for(auto &v:b)cin>>v;
	ll ans=0;
	int loc1=0, loc2=0;
	while(1){
		while(loc1<n && a[loc1]<=b[loc1])loc1++;
		while(loc2<n && a[loc2]>=b[loc2])loc2++;
		if(loc1==n && loc2==n)break;
		if(loc1==n && loc2!=n){
			cout<<-1<<'\n';
			return;
		}
		if(loc1!=n && loc2==n){
			cout<<-1<<'\n';
			return;
		}
		int d1=a[loc1]-b[loc1], d2=b[loc2]-a[loc2];
		if(d1%2 || d2%2){
			cout<<-1<<'\n';
			return;
		}
		if(d1>=d2){
			b[loc1]+=d2;
			b[loc2]-=d2;
			ans+=1LL*d2/2*abs(loc1-loc2);
		}else{
			a[loc2]+=d1;
			a[loc1]-=d1;
			ans+=1LL*d1/2*abs(loc1-loc2);
		}
	}
	for(int i=0; i<n; i++){
		if(a[i]!=b[i]){
			cout<<-1<<'\n';
			return;
		}
	}
	cout<<ans<<'\n';
}
int main(void)
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T=1;cin>>T;
	while(T--)solve();
	return 0;
}

标签:传递,练习赛,int,ll,loc2,牛客,108,loc1,d2
From: https://www.cnblogs.com/JustACommonMan/p/17129666.html

相关文章

  • 牛客练习赛46
     题目描述奕奕的几何很差,然而奕奕并不承认,所以华华扔给奕奕一道题目。如图:已知大半圆的半径等于两个小半圆半径之和。若给出红色部分的面积,那么大圆的半径最小是多少呢?反......
  • 【牛客网】字符串分隔
    题目描述•输入一个字符串,请按长度为8拆分每个输入字符串并进行输出;•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。输入描述:连续输入字符串(每个字符串......
  • 【牛客网】明明的随机数
    题目描述明明生成了N个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。数据......
  • 【牛客网】计算某字符的出现次数
    题目描述写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)数据范围:1≤n≤1000输入描......
  • 【牛客网】字符串的最后一个单词的长度
    题目描述计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)输入描述:输入一行,代表要计算的字符串,非空,长度小于5000。输出......
  • 牛客小白月赛12 -- E 华华给月月准备礼物 (二分)
     题目描述二月中旬虐狗节前夕,华华决定给月月准备一份礼物。为了搭建礼物的底座,华华需要若干根同样长的木棍。华华手头上有一些长度参差不齐的木棍,他想将每根都裁剪成若干......
  • 牛客小白月赛12 -- B 华华教月月做数学
     题目描述找到了心仪的小姐姐月月后,华华很高兴的和她聊着天。然而月月的作业很多,不能继续陪华华聊天了。华华为了尽快和月月继续聊天,就提出帮她做一部分作业。月月的其中......
  • 牛客练习赛 108 题解
    六道题目的出题人都是我,希望大家玩的开心!https://ac.nowcoder.com/acm/contest/51208A.惊鸿显然位或之后只会变大,因此答案为\(4\times(a_1\text{or}a_2\text{or}......
  • 【牛客刷题】HJ68 成绩排序
    题目链接这题本身就是一个排序题,按照学生成绩排序,成绩一样的按照输入的前后顺序排。如果用Java,那么利用ArrayList能很轻松的完成:importjava.util.ArrayList;importja......
  • 【牛客刷题】HJ15 求int型正整数在内存中存储时1的个数
    题目链接题倒是很简单,最开始用了这么一种解法:packagemainimport"fmt"funcmain(){ a:=0 fmt.Scan(&a) str:=fmt.Sprintf("%b",a) fmt.Printf("%d",co......