zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 063

    AtCoder Beginner Contest 063 - D - Widespread (二分答案)

    Time Limit: 2 sec / Memory Limit: 256 MB

    Score : 400 points

    Problem Statement

    You are going out for a walk, when you suddenly encounter NN monsters. Each monster has a parameter called health, and the health of the ii-th monster is hihi at the moment of encounter. A monster will vanish immediately when its health drops to 00 or below.

    Fortunately, you are a skilled magician, capable of causing explosions that damage monsters. In one explosion, you can damage monsters as follows:

    • Select an alive monster, and cause an explosion centered at that monster. The health of the monster at the center of the explosion will decrease by AA, and the health of each of the other monsters will decrease by BB. Here, AA and BB are predetermined parameters, and A>BA>B holds.

    At least how many explosions do you need to cause in order to vanish all the monsters?

    Constraints

    • All input values are integers.
    • 1≤N≤1051≤N≤105
    • 1≤B<A≤1091≤B<A≤109
    • 1≤hi≤109

    Input

    Input is given from Standard Input in the following format:

    NN AA BB
    h1h1
    h2h2
    ::
    hNhN
    

    Output

    Print the minimum number of explosions that needs to be caused in order to vanish all the monsters.

    Sample Input 1 Copy

    Copy

    4 5 3
    8
    7
    4
    2
    

    Sample Output 1 Copy

    Copy

    2
    

    You can vanish all the monsters in two explosion, as follows:

    • First, cause an explosion centered at the monster with 88 health. The healths of the four monsters become 33, 44, 11 and −1−1, respectively, and the last monster vanishes.
    • Second, cause an explosion centered at the monster with 44 health remaining. The healths of the three remaining monsters become 00, −1−1 and −2−2, respectively, and all the monsters are now vanished.

    Sample Input 2 Copy

    Copy

    2 10 4
    20
    20
    

    Sample Output 2 Copy

    Copy

    4
    

    You need to cause two explosions centered at each monster, for a total of four.

    题意:

    你面对n个怪兽,第i个怪兽有h[i]健康值,你每一次攻击可以选择一个还活着的怪兽,然后使其健康值下降A,其他的怪兽的健康值下降B。当一个怪兽的健康值小于等于0时,这个怪兽就会消失。

    现在问你最少需要多少次攻击可以使所有的怪兽都消失。

    思路:

    设函数F(x)代表攻击x次,最多可以消灭怪兽的数量。

    容易知道该函数是一个单调不下降的函数。

    于是我们可以二分答案ans,二分过程中去检测攻击ans次是否可以消灭所有怪兽。

    距离检测过程为:

    将所有怪兽健康值h[i]减去 ans*b, 减去后的h[i]仍大于0的 再减去(cnt_i= lceil frac{h[i]}{(A-B)} ceil)

    (注意h[i] 减去了ans*b后的)

    然后返回(ans>=sum_{i=1}^n cnt_i) 即可。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n;
    ll h[maxn];
    ll b, a;
    bool check(ll x)
    {
    	ll res = x;
    	repd(i, 1, n)
    	{
    		ll temp = h[i] - x * b;
    		if (temp > 0)
    		{
    			ll need = temp / (a - b);
    			if (temp % (a - b) != 0)
    			{
    				need++;
    			}
    			res -= need;
    			if (res < 0)
    			{
    				break;
    			}
    		}
    	}
    	return res >= 0;
    }
    int main()
    {
    	//freopen("D:\code\text\input.txt","r",stdin);
    	//freopen("D:\code\text\output.txt","w",stdout);
    	n = readint();
    	a = readll();
    	b = readll();
    	repd(i, 1, n)
    	{
    		h[i] = readll();
    	}
    	ll l = 1ll;
    	ll r = inf;
    	ll mid;
    	ll ans;
    	while (l <= r)
    	{
    		mid = (l + r) >> 1;
    		if (check(mid))
    		{
    			ans = mid;
    			r = mid - 1;
    		} else
    		{
    			l = mid + 1;
    		}
    	}
    	printf("%lld
    ", ans );
    	return 0;
    }
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    TLS Version 1.0 Protocol Detection 漏洞修复
    更新ESXI版本
    CentOS7禁止PING的方法
    Nginx_ingress配置ssl_dhparam
    Nessus安装与使用
    centos7的防火墙不能控制docker容器端口的问题
    centos 7 安装mariadb
    CentOS7 ICMP漏洞修复
    如何基于LSMtree架构实现一写多读
    vitual box 安装centos7
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/12288011.html
Copyright © 2011-2022 走看看