codeforces1359C. Mixing Water

題目鏈接

現有兩水源,一個熱水h度,另一個涼水c度,然後你往體積無限的桶裏一瓢熱的一瓢涼的倒,問倒幾瓢離t度最接近


顯然這題答案只有兩種,要麼是2,要麼2n+12n+1

 證明如下:
 - 當混合了$2n$次之後,溫度

td=n(h+c)2n=h+c2 t_d = \frac{n(h+c)}{2n}=\frac{h+c}{2}

 可見偶數次混合後溫度恆定

 - 當混合了$2n+1$次後,溫度

td=n(h+c)+h2n+1 t_d = \frac{n(h+c)+h}{2n+1}

其中$t_d(n+1)-t_d(n)<0$故混合溫度單調遞減且收斂於$\frac{h+c}{2}$

綜上可知:

  • 對於th=c2t\leq \frac{h=c}{2}時,混合2次即可
  • th=c2t\geq \frac{h=c}{2}時需要計算次數

下面就第二種情況,即答案爲2n+12n+1的情況做說明:
根據tdt_d的單調性可知,對於t>h+c2\forall t>\frac{h+c}{2}必然存在唯一解;且藉助單調性,可以用二分進行更高效的查找。但由於涉及浮點運算,所以注意精度或將double換爲longlong

最後解釋一下 爲什麼double存在精度問題

#pragma GCC diagnostic error "-std=c++11"
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

template<class T> void _deb(const char *name,T val){
    cout<<name<<val<<endl;
}


int t;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin>>t;
    while(t--){
        double h,c,t;
        cin>>h>>c>>t;
        if((int)t<=(int)((h+c)/2)){
            cout<<2<<endl;
            continue;
        }

        int inf=0,sup=6e5;
        while(inf+1<sup){
            int mid=inf+(sup-inf)/2;
            double n=mid*2+1;

            double tem=((h+c)*mid+h)/n;
            if(tem<t)
                sup=mid;
            else
                inf=mid;
        }
        double abs1=abs(t-((h+c)*inf+h)/(2*inf+1));
        double abs2=abs(t-((h+c)*sup+h)/(2*sup+1));
        if(abs1-abs2<1e-15)
            cout<<2*inf+1<<endl;
        else
            cout<<2*sup+1<<endl;
    }

    re 0;
}

但是看過答案之後,終究還是感嘆於自身的zz,能O(1)算出來的東西爲啥還得二分再找呢。。。
我們已知混合了2n+12n+1次後的溫度爲
td=n(h+c)+h2n+1 t_d = \frac{n(h+c)+h}{2n+1}
th+c2t\geq \frac{h+c}{2}時,不難求出混合後第一次小於t的次數2i+12i+1
td=i(h+c)+h2i+1t t_d =\frac{i(h+c)+h}{2i+1} \leq t
且這個函數是單調遞減的,所以答案就在2i+12i+12(i1)+12(i-1)+1之中,只需要單獨計算並比較差值即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章