AtCoder Regular Contest 075 D - Widespread 二分
题目链接:
http://arc075.contest.atcoder.jp/tasks/arc075_b
题意:
有n个怪物,每个怪物有hi点血,每攻击一次,可以选择一个怪物使他减去A点血,对其他所有怪物伤害B点,(A>B), 问最少攻击几次,才能干掉所有怪物
思路:
我们可以二分攻击的次数t,先对所有怪物伤害t*B,对于还有血的怪物,判定是否可以用t次(A-B)的伤害干掉。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 1e5+10; 17 18 ll x[maxn],k[maxn]; 19 ll n,a,b; 20 21 bool check(ll t){ 22 memcpy(k,x,sizeof(x)); 23 for(ll i=1; i<=n; i++){ 24 k[i] -= t*b; 25 } 26 ll more = (a-b),cnt=0; 27 for(ll i=1; i<=n; i++){ 28 if(k[i]>0) cnt += (k[i]%more==0) ? (k[i]/more) : (k[i]/more+1); 29 } 30 return cnt <= t; 31 } 32 33 int main(){ 34 cin >> n >> a >> b; 35 for(int i=1; i<=n; i++){ 36 x[i] = read(); 37 } 38 39 ll ans,L=1,R=1e9; 40 while(L<=R){ 41 ll mid = (L+R)/2; 42 if(check(mid)) ans=mid,R=mid-1; 43 else L=mid+1; 44 } 45 46 cout << ans << endl; 47 48 49 return 0; 50 }