codeforces 1065 C. Make It Equal(差分+貪心)
阿新 • • 發佈:2018-12-16
題意:有n座塔,塔高h[i],每次給定高度H對他們進行削切,要求每次削掉的所有格子數不能超過k個,輸出最少削幾次才能使所有塔的高度相同。
思路:
比較明顯,只要知道對應的每層高度有多少個格子,然後再從高到低下來使其符合<k的條件即可。
而去求得每層高度對應多少個格子,暴力跑肯定是不行的。
正確的方法:
第一層的格子數是n個,對於每輸入的高度h,肯定該塔對應的h+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; }