【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;
}
posted @ 2020-05-29 07:37  AWCXV  阅读(531)  评论(2编辑  收藏  举报