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;
}

浙公网安备 33010602011771号