ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

均衡操作2

2022-09-11 12:34:23  阅读:191  来源: 互联网

标签:10 数列 桶子 均衡 操作 变成 倒掉 数字


 

小J面前有N桶水,每个桶装的水的体积不一样

现在小J希望让所有桶的水的体积变得一样

每次他会选择两个相邻的桶子, 将桶中的水都倒掉1个单位

问他至少倒掉多少水,使得所有桶的水一样多,如果达不到目的,输出-1

Format
Input
第一行给出数字T,代表数据的组数

对于每组数据,先给出N 下面一行给出N个数字,代表每个桶的水的体积

N<=1e5

体积<=1e9

Output
如题

Samples
输入数据 1
2
3
8 10 5
6
4 6 4 4 6 4
输出数据 1
14
16
Hint

第1次,将第2个与第3个桶子都倒掉2个单位的水

第2次,将第1个与第2个桶子都倒掉5个单位的水

 

Sol:我们先来看样例的操作过程 

既然要让所有数字变得一样,那当然要找到最大的那个数字10,让10与5一起减少2,这样10就变成了8

与左边的8变成一样。于是变成

8 8 3

然后再将最左边两个数字8 8一起减少5,得到 3 3 3.

此时我们会发现,如果每次在要数列中找最大值来减,是个比较麻烦的事。

又发现,在整个操作中,只要最终达到目的,先减哪个,再减哪个,并不重要。。。。

于是仍以样例来说

8 10 5

我们的目标是让所有数字变成一样

于是对于10来说,它比左边的8大,于是10就要变小,而按题意,相邻的两个数字都要变

于是10就拉上右边的5一起变,变成

8 8 3

通过这样的变化,我们能使整个数列的第1个数字到第N-1数字,它们会变成一个不上升的数列(当然最理想的状态是前N-1个数字变得一样了)

接下来,我们可以将8 8 3倒过来得到3 8 8

再按上面的思路做一遍得到3 3 3

当然这个操作过程中还两个细节

1:

在做完第一遍操作后,整个数列必须是一个不上升的数列,否则是无解的。

例如

8 10 20

这个数据就是无解的。

 

2:在做第二遍的时候,必须保证最左边那个数字是不能为负数的

例如数据

6 10 3

如果让10与3一起减少4的话,则3会变成-1.

后面的操作就无法进行下去的。。。。。。。负数怎么减少啊!!!

 

总结:

1:这个题其实是一种步步逼近的方式

2:如果发现操作的先后顺序与最终结果没有关系 ,就不妨统统从左向右做。。。类似于NOIP那个经典题均分纸牌。

#include<bits/stdc++.h>
#define int long long
#define isdight(c) (c>='0'&&c<='9')
#define swap(a,b) a^=b^=a^=b
using namespace std;
int t,n,h[100005];
inline int read() //快读
{
	int x=0,f=1;
	char c=getchar();
	while(!isdight(c))
		f=(c^'-'?1:-1),c=getchar();
	while(isdight(c))
		x=(x<<1)+(x<<3)+c-'0',c=getchar();
	return x*f;
}
int solve()
{
	int ans=0;
	if(n<2)
		return 0; //无需改变
	for(int j=1;j<=2;j++) //正序变化与倒序变化
	{
		for(int i=2;i<n;i++)
		{
			if(h[i]>h[i-1])
			{
				int differ=h[i]-h[i-1];
				ans+=differ*2; //每次喂两袋
				h[i+1]-=differ;
				h[i]=h[i-1]; //同时变化
			}
		}
		if(h[n]>h[n-1])
			return -1; //无解
		if(h[n]<0)
			return -1; //无解
		reverse(h+1,h+1+n); //反转
	}
	return ans;
}
signed main()
{
	t=read();
	while(t--)
	{
		n=read();
		for(int i=1;i<=n;i++)
			h[i]=read();
		printf("%lld\n",solve());
	}
	return 0;
}

  

标签:10,数列,桶子,均衡,操作,变成,倒掉,数字
来源: https://www.cnblogs.com/cutemush/p/16683777.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有