阶梯(C)

You came to the exhibition and one exhibit has drawn your attention. It consists of nn stacks of blocks, where the ii-th stack consists of aiai blocks resting on the surface.

The height of the exhibit is equal to mm. Consequently, the number of blocks in each stack is less than or equal to mm.

There is a camera on the ceiling that sees the top view of the blocks and a camera on the right wall that sees the side view of the blocks.
在这里插入图片描述
Find the maximum number of blocks you can remove such that the views for both the cameras would not change.

Note, that while originally all blocks are stacked on the floor, it is not required for them to stay connected to the floor after some blocks are removed. There is no gravity in the whole exhibition, so no block would fall down, even if the block underneath is removed. It is not allowed to move blocks by hand either.

Input
The first line contains two integers nn and mm (1≤n≤1000001≤n≤100000, 1≤m≤1091≤m≤109) — the number of stacks and the height of the exhibit.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤m1≤ai≤m) — the number of blocks in each stack from left to right.

Output
Print exactly one integer — the maximum number of blocks that can be removed.
Examples
Input
5 6
3 3 3 3 3
Output
10
Input
3 5
1 2 4
Output
3
Input
5 5
2 3 1 4 4
Output
9
Input
1 1000
548
Output
0
Input
3 3
3 1 1
Output
1

思路:

先把每一堆排好序,然后逐个判断,从1----n-1列的判断方式是如果本列的块数比上一列的最高层数大,则最高层数加一,并且每次判断让必须留下的块数+1(其实易知1~n-1列都是只有一个的,可以直接让计数器的个数等于n-1),再判断第n列,第n列的需要必须留下的块数为:第n列的个数减去最高层数(这一点看下面那张图就很好理解),最后输出总块数减去必须留下的块数即为最多能去除的块数。
我感觉我还得解释一下我这里说的最高层的意思就是下面图中前i列在保留完毕后第i列保留块的高度,比如下面这个图,第n-1列保留块的高度为9,则最高层数就是9
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h> //快速排序在这个头文件里
#define MAXN 100000
long long int a[MAXN];
int comp(const void*a,const void*b)
{
	return *(int*)a-*(int*)b;
} //自己写上这一段代码,判断快排是升序还是降序,这里是升序,若要降序,只需把a和b位置互换
int main()
{
	long long int n,m;
	long long int cnt=0,sum=0,mnum=0;
	scanf("%lld %lld",&n,&m);
	for(long long int i=0;i<n;i++)
	{
		scanf("%lld",&a[i]);sum=sum+a[i]; //输入顺便求下块数总和
	}
	qsort(a,n,sizeof(long long int),comp); //快排 需要数据 数组a,数组a的长度,数组a数据类型的大小,以及comp返回的值来判断是升序还是降序。
	for(long long int i=0;i<n-1;i++) if(a[i]>mnum)mnum++; //计算出最高层数
	cnt=n-1; //根据规律直接得出前n-1列保留的块数
	if(a[n-1]-mnum>1) //判断第n列情况
	cnt+=(a[n-1]-mnum);
	else
	cnt++;
	printf("%lld",sum-cnt);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值