1. 程式人生 > >codeforces 1065 C. Make It Equal(差分+貪心)

codeforces 1065 C. Make It Equal(差分+貪心)

題意:有n座塔,塔高h[i],每次給定高度H對他們進行削切,要求每次削掉的所有格子數不能超過k個,輸出最少削幾次才能使所有塔的高度相同。

思路:

比較明顯,只要知道對應的每層高度有多少個格子,然後再從高到低下來使其符合<k的條件即可。

而去求得每層高度對應多少個格子,暴力跑n^{2}肯定是不行的。

正確的方法:

第一層的格子數是n個,對於每輸入的高度h,肯定該塔對應的h+1高度的格子就沒有了,所以每次輸入,h[hh+1]--即可,這樣上一層的格子數減去(h[]本來就是<=0的了)這一層減少了的格子數就是本層的格子數了。 (這種對於塔高度如 1  3  5,的也沒有影響,反正h[2]=-1,h[3]=0,該減的地方減了,不用減的地方也為0了,符合的)

要注意的:

1.最後跳出迴圈後,如果累計的格子數tmp之前是沒有超過k的,且還有剩餘的,仍然是需要削去的,即ans++;

2.可能會出現的一個特例,只有一座塔時,或者所有塔的高度都相等時,輸出應為0,不是1或其他的(下面這個程式碼可以忽略這種情況的考慮)

#include <bits/stdc++.h>
//#pragma GCC optimize(3)
//#pragma GCC optimize("unroll-loops")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define mkp(a,b) make_pair(a,b)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define fi first
#define se second
#define lc (d<<1) //d*2
#define rc (d<<1|1) //d*2+1
#define eps 1e-9
#define dbg(x) cerr << #x << " = " << x << "\n";
#define mst(a,val) memset(a,val,sizeof(a))
#define stn(a) setprecision(a)//小數總有效位數
#define stfl setiosflags(ios::fixed)//點後位數:cout<<stfl<<stn(a);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double PI=3.1415926535897932;
const int MAXN=1e5+10;
const ll mod=1e9+7;
ll inline mpow(ll a,ll b){ll ans=1;a%=mod;while(b){if(b&1)ans=(ans*a)%mod;a=(a*a)%mod,b>>=1;}return ans;}
int inline sgn(double x){return (x>-eps)-(x<eps);} //a<b:sgn(a-b)<0
priority_queue<int,vector<int>,greater<int> > qu; //up
priority_queue<int,vector<int>,less<int> > qd; //dn
const int inf = 0x3f3f3f3f; //9
const ll inff = 0x3f3f3f3f3f3f3f3f; //18

int n,k;
int h[200010];
int hh;
int ans;

int main()
{
    fio;
    cin>>n>>k;
    int mi=inf;
    for(int i=0;i<n;i++)
    {
        cin>>hh;
        mi=min(mi,hh);
        h[1]++; h[hh+1]--;
    }
    for(int i=1;i<=200000;i++) h[i]+=h[i-1];
    ll tmp=0;
    for(int i=200000;i>mi;i--)
    {
        tmp+=h[i];
        if(tmp>k) {ans++;i++;tmp=0;}
    }
    if(tmp) ans++;
    cout<<ans<<endl;
}