連絡先を考えCF - CodeForces - 991Cキャンディーズ(半分)

セットを訓練ACM思考の質問

試験に合格した後、Vasyaは彼自身のnキャンディーの箱を得ました。彼はこれ以上のキャンディーがなくなるまで毎朝キャンディーの同量を食べることにしました。しかし、ペチャも箱に気づき、自分自身のためにいくつかのキャンディーを取得することを決めました。

この手段キャンディーを食べるのプロセスは以下の通りです:最初にVasyaは全ての日に同じ単一の整数kを、選択します。その後、午前中に彼は、(ボックスに少ないk個のキャンディーよりも存在する場合、彼はそれらすべてを食べる)箱からk個のキャンディーを食べた後、夕方にキャンディーのペチャ食べる10%がボックス内に残っています。まだボックスに残っキャンディーている場合は、このプロセスが繰り返さ - 再び翌日Vasya食べるk個のキャンディー、およびペチャは - キャンディーの10%がボックス内に残され、というように。

ボックス内のキャンディーの量が10で割り切れない場合は、ペチャは、彼が箱の下から取る量を丸めます。ボックス内の97のキャンディーがあった場合たとえば、ペチャはわずか9それらのを食べます。10未満のキャンディーがボックス内に存在する場合、特に、ペチャはまったく食べられないだろう。

あなたの仕事は、彼が最初に得たn個のキャンディーの少なくとも半分で食べるようにVasyaによって選ぶことができるkの最小限の量を見つけることです。数kは整数でなければならないことに留意されたいです。

入力
ボックスにキャンディーの初期量-最初の行は、単一の整数n(1≤n≤1018)を含みます。

出力
出力単一の整数- Vasyaは、彼が得たキャンディーの少なくとも半分で食事できるようになるkの最小限。

例えば
入力
68
出力の
3

K = 3のサンプルでは、キャンディーの量は、(第一Vasyaの食事)を以下のように変化します。

68→65→59→56→51→48→44→41→37→34→31→28→26→23→21→18→17→14→13→10→9→6→6→3→3→ 0。

合計で、Vasya 39のキャンディーを食べる 29 -ペチャながら、
需要が最小であるので、列挙するために、または乗算が、列挙タイムアウト必要が単調倍増ので、直接バイナリとして単調性を検証します。
半分は使用することができますが、この問題はそれだけで、プライオリティキュー、マップ、セット、半分がない他の適切なアルゴリズムに加えて、複雑なlog2nを使用してデータを読み取ることができた後。
そして、以下ではない話題、以上で、質問の明確な意味を読んでいない、等号は半分の時間でチェックするために注意を払っていません。

#include <bits/stdc++.h>
using namespace std;
template <typename t>
void read(t &x)
{
    char ch = getchar();
    x = 0;
    t f = 1;
    while (ch < '0' || ch > '9')
        f = (ch == '-' ? -1 : f), ch = getchar();
    while (ch >= '0' && ch <= '9')
        x = x * 10 + ch - '0', ch = getchar();
    x *= f;
}

#define wi(n) printf("%d ", n)
#define wl(n) printf("%lld ", n)
#define rep(m, n, i) for (int i = m; i < n; ++i)
#define rrep(m, n, i) for (int i = m; i > n; --i)
#define P puts(" ")
typedef long long ll;
#define MOD 1000000007
#define mp(a, b) make_pair(a, b)
#define N 10005
#define fil(a, n) rep(0, n, i) read(a[i])
//---------------https://lunatic.blog.csdn.net/-------------------//
bool check(long long k, long long sum)
{
    ll a = 0, b = 0;
    while (sum)
    {
        //  cout<<a<<" "<<b<<endl;
        if (sum >= k)
        {
            sum -= k;
            a += k;
        }
        else
        {
            a += sum;
            sum = 0;
        }
        if (sum >= 10)
        {
            long long tem = sum / 10;
            b += tem;
            sum -= tem;
        }
    }

    return a >= b;  //这没等号会错//
}
int main()
{
    long long sum;
    read(sum);
    ll l = 1, r = sum;
    while (l < r)
    {
        ll mid = (l + r) / 2;
        if (check(mid, sum))
            r = mid;

        else l=mid+1;
    }
    cout<<l<<endl;
}
公開された578元の記事 ウォンの賞賛253 ・は 40000 +を見て

おすすめ

転載: blog.csdn.net/weixin_43627118/article/details/104599818