1. 程式人生 > >Codeforces1065C——Make It Equal

Codeforces1065C——Make It Equal

題目省略

思路不清晰,後面想複雜了,然後就tle了
題意是給一個數列,代表每個建築的高度,然後水平一刀切下去,每次拿走的不能超過k個,然後要切多少次才能切平
首先讀取每一個高度的時候記錄下最大和最小的,最小的其實就是切平的位置,所以以下的都不用管了,然後先記錄每一個高度出現的次數,然後用字首和就可以記錄每一層的塊的個數了,比如高度為4的有2個,那麼第四層的塊的個數就等於2,而第三層的塊的個數就等於高度為3的個數加上第四層塊的個數,因為能到第四層肯定能到第三層
然後就On遍歷這個字首和陣列,記錄臨時和,如果小於k就繼續加,直到大於k就切一刀,然後臨時和變成這一層的塊的個數

程式碼:

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=2*1e5+50;
const int INF=0x3f3f3f3f;
int a[N];
int h[N];
int num[N];
int cnt[N];
int pre[N];
int n,k;
int main(void){
    int maxH=0;
    int minH=INF;
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++
){ scanf("%d",&h[i]); maxH=max(maxH,h[i]); minH=min(minH,h[i]); num[h[i]-1]++; } //特判 if(minH==maxH){ printf("0\n"); return 0; } num[maxH]=0; //字首和思想求出每一層的個數(需要刪除的層) for(int i=maxH-1;i>=minH;i--){ cnt[i]=cnt[i+1]+num[
i]; } int ans=1; int tmp=0; for(int i=1;i<=maxH;i++){ if(tmp+cnt[i]<=k){ tmp+=cnt[i]; } else{ ans++; tmp=cnt[i]; } } printf("%d\n",ans); return 0; }