问题:怪兽

题目描述

    你正在与n只怪兽作战。第i只怪兽有血量a[i],a[i]是整数。当a[i]<=0时,第i只怪兽死亡。你可以施展如下两种法术:

(1)   给某一只怪兽i造成一点伤害

(2)   给所有怪兽造成1点伤害,并且若在施展该法术后有怪兽死亡,会再次释放该法术。直到某一次释放后没有怪兽死亡为止。

 

造成一点伤害,怪兽的血量就会减少一点。法术1可以无限释放,法术2只能主动释放一次。请问杀死所有怪兽至少需要释放法术1多少次?0

输入

第一行一个整数t(1<=t<=10000)表示数据组数

    每组数据包含两行,第一行一个整数n(1<=n<=200000),第二行n个整数a[i](1<=a[i]<=n)

    数据保证所有的n的和不超过200000

输出

    对于每组数据,输出一个整数表示至少释放多少次法术1

样例输入

2
3
3 1 2
6
4 1 5 4 1 1

样例输出

0
4
 

做法

粗说——这里只要判断一下a[i]+1是否能等于a[i+1],就说明能连续释放法术1,可以不计,或如果是a[i]=a[i+1]就说明使用法术1能每一个都减1,那就从0开始。

细说—— 相等的情况:

1
5
2 2 2 2 2 

从0开始就可以把第1个减去1,就发现后面都不用变了。

因此,得出结论:

如果有n个相等数字,只要变动a[1]-1次就行了。

这是相等的情况。

不相等的情况:

1
5
1 2 4 5 6

(如果顺序是逆序,一定要sort)

我们就判断a[i]是否等于a[i+1]+1

加1代表能连续释放法术1,否则-(a[i+1]-a[i]-1)(为了提高速度)

以上就是两种情况。

代码(加了scanf和printf,否则超时)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll T,n,i,a[200010],tot,sum;
int main() {
	scanf("%d",&T);
	while(T--) {
		scanf("%d",&n);
		for(i=1; i<=n; i++)
			scanf("%d",&a[i]);
		sort(a+1,a+1+n);
		sum=0;
		for(i=0; i<n; i++)
			if(a[i]!=a[i+1]&&a[i]+1!=a[i+1])
				tot=(a[i+1]-a[i]-1),sum+=tot,a[i+1]-=tot;
		printf("%d\n",sum);
	}
}

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值