【Educational Codeforces Round 88 (Rated for Div. 2) C】 Mixing Water


題目鏈接

【題目翻譯】

有一個無限大的容器。

你輪流進行如下操作:倒一杯熱水進去、倒一杯冷水進去。以此類推。

(熱水溫度是h,冷水溫度是c)

容器中的水的溫度等於倒進去的水的溫度總和/倒水的次數。

問你需要進行多少次操作,水的溫度才能最接近溫度t。

【題解】

會發現,進行2,4,6,8,10...次操作,水的溫度都是(h+c)/2.

並且因為是先倒熱水,所以在水的溫度的變化過程中,水溫始終是大於(h+c)/2.

因此,對於給定的溫度t如果是<=(h+c)/2,那么直接輸出2就行了,因為那是你能到達的最小的溫度了(然后操作次數最少).

因為2,4,6,8...這些正偶數操作次數水溫都是\(\frac{h+c}{2}\),所以我們不考慮他們了。

直接考慮操作次數為1,3,5,...的,然后發現這些操作對應的水溫是一個單調遞減的數字(試出來的,嘻嘻)(如果t給的值等於h,則直接輸出1)

然后就寫個二分,找到最小的小於t的溫度對應的操作次數(我這里二分的是它是1,3,5,...中的第幾個,第x個對應了第1+x*2次操作)就好。

然后和第i-2次操作比較一下,看哪個溫度和t距離比較近(相等的話輸出i-2)

二分的上限一開始是50W(這個數字是我大概根據比較大的數字的出來的迭代次數),交上去WA了,然后就加了個0,再交了一發。

當時只剩5分鍾了,我提交的結果都沒敢去看。。直接去檢查細節去了。沒檢查出來什么東西,然后回過頭看看提交結果,YES!!!

不過這會還沒hack結束,不知道會不會掛終測:)

【代碼】

#include<bits/stdc++.h>
#define ll long long
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x)
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
using namespace std;

const int N = 1000;

int T;

int main(){
    //cout<<(1LL<<62)<<endl;
    #ifdef LOCAL_DEFINE
        freopen("D:\\rush.txt","r",stdin);
    #endif
    ios::sync_with_stdio(0),cin.tie(0);
    cin >> T;
    while (T--){
        int h,c,t;
        cin >> h >> c >> t;
        if (t*2<=h+c){
            cout<<2<<endl;
        }else{
            if (t==h){
                cout<<1<<endl;
            }else{
                //h/2<t<h
                ll tmp;
                double pans = h-t;
                ll l = 1,r = 5000000,temp = 0;
                while (l<=r){
                    ll mid = (l+r)/2;
                    ll i = 1+mid*2;
                    tmp = h + (h+c)*mid;
                    if (tmp%i==0){
                        if (tmp/i==t){
                            temp = mid;
                            break;
                        }
                    }
                    double fenzi = tmp;
                    double fenmu = i;
                    double ans = fenzi/fenmu;
                    if (ans<t){
                        temp = mid;
                        r = mid - 1;
                    }else{
                        l = mid + 1;
                    }
                }
                ll i = 1+temp*2;
                tmp = h + (h+c)*temp;
                if (tmp%i==0 && tmp/i==t){
                    cout<<i<<endl;
                }else{
                    ll pi = i-2;
                    ll ptmp = tmp-h-c;
                    double pans = (1.0*ptmp)/(1.0*pi) - t;
                    double ans = t-(1.0*tmp)/(1.0*i);
                    if (pans<=ans){
                        cout<<i-2<<endl;
                    }else{
                        cout<<i<<endl;
                    }
                }
            }
        }
    }
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM