C-Hacking Numbers

题目链接:https://codeforces.com/contest/2109

题意:

交互题

有一个未知数x(1<=x<=1e18),给定n。目的是把x变为n

四种操作
1.add
输入一个数y,让x+y。如果结果小于0,则返回-1,否则返回1,并改变x原来的值

2.mul
与add同理,不过是乘以y

3.div
如果y是x的除数,则...

4.digit
将x变为它各数位上的和

C1:至多7次操作,让x变为n
C2:至多4次操作,让x变为n
C3:用最少的操作次数,让x变为n

思路:

由于不知道x的大小,所以需要将x变为一个能确定的数
发现1是特殊的边界点,所以不妨将x变为1

通过两次digit能使x[1,1e9]的数变为[1,16](最大999999999,digit一次值域变为[1,81],因此第二次digit最大79,值域[1,16])
通过折半查找将x变为1,再乘以n(加上n-1)即可

发现一个数如果是9的倍数,其各位之和也是9的倍数
先让x乘以9,9x[9,9e9]再digit[9,90](且是9的倍数)(【9,18,27,36,45,54,63,72,81,90】,99,108,117...,99其实加起来就是18了)再digit一定变为9

S(x*(10^d-1))=9xd(x[1,10^d])

让x乘以999999999则x变为81,再根据n的判断是否直接返回或者+n-81

注意交互题每次输出时都要加endl,以及flush,并且交互机返回的值也要读入进去,不然WA

int query(int q,int x=-1){
    if(q==1){
        cout<<"add "<<x<<endl;
    }else if(q==2){
        cout<<"mul "<<x<<endl;
    }else if(q==3){
        cout<<"div "<<x<<endl;
    }else if(q==4){ 
        cout<<"digit"<<endl;
    }else{
        cout<<"!"<<endl;
    }
    cout<<flush;
    int res;cin>>res;return res;
}
posted @ 2025-05-20 20:26  Marinaco  阅读(20)  评论(0)    收藏  举报
//雪花飘落效果