• Codeforces 1065C Make It Equal


    难受的很......比赛时候写出来正解高兴得不得了结果少了特判被hack+fst了.......难受

    题意:

    给定N个由高度相同的方块摞起来的塔,一次操作能将高度在某个值以上的方块全部消除,代价为消去的方块数量。

    规定每次操作代价不能超过给定的K,求至少经过多少次操作才能将所有塔的高度变得相同。

    题解:

    首先把所有塔的高度减去其中的最小值,问题就变成了将塔消完所需要的步数。

    然后维护一个前缀和数组 $ b $ , $ b[i] $ 表示有多少塔的高度(削过之后)大于 $ i $ 。

    或者可以理解为:在高度为 $ i $ 处有多少方块。

    这样我们就得到了一个一维数组b。

    由于每次操作都会消去一层或多层内所有方块,所以可以将数组b理解为「一层一层消,每次所需要的代价」。

    接下来所要做的就是合并这些代价,使合并后每段的和都不超过给定的k。

    合并后有几段,就是需要操作多少次。

    注意特判

    · 如果只有一个塔,那么直接输出0.

    · 如果所有塔高度相同,那么直接输出0.

    
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define LL long long
    using namespace std;
    LL n,k;
    int a[200050];
    bool cmp(int x,int y){
    	return x>y;
    }
    int minn=2147483647,maxn=0;
    int b[200050];
    int main(){
    	scanf("%lld%lld",&n,&k);
    	for(int i(1);i<=n;i++)scanf("%d",&a[i]),minn=min(minn,a[i]),maxn=max(maxn,a[i]);
    	if(n==1){
    		cout<<0;
    		return 0;
    	}
    	for(int i(1);i<=n;i++){
    		a[i]-=minn;
    		b[1]++;
    		b[a[i]+1]--;
    	}
    	for(int i(2);i<=n;i++){
    		if(a[i]!=a[1])break;
    		if(i==n){
    			cout<<0;
    			return 0;
    		}
    	}
    	for(int i(2);i<=maxn;i++)b[i]+=b[i-1];
    	int tmp=0,ans=1;
    	for(int i(1);i<=maxn;i++){
    		if(tmp+b[i]<=k)tmp+=b[i];
    		else ans++,tmp=b[i];
    	}
    	printf("%d",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    VUE中is的作用
    lable便签 for的作用
    Java第五课
    Java第四课课后作业
    Java第四课
    Unit6Java运算符
    Unit5Java数据类型
    Unit4如何使用类
    Java如何设计并编写类
    IDEA安装Alibaba,SonarLint代码规范检查插件
  • 原文地址:https://www.cnblogs.com/soul-M/p/9776086.html
Copyright © 2020-2023  润新知