Помогите решить задачу №1768 из acmp.ru
Текст задания:
Это интерактивная задача.
Антона в очередной раз пригласили принять участие в марафоне, но этот марафон оказался довольно необычным — он проводился на стадионе!
Антона позвали в другой город, поэтому про стадион, на котором он собирается бежать, ему ничего не известно (даже примерно). Чтобы скрасить свое участие в этом довольно скучном событии, он поставил перед собой задачу — узнать длину кругового участка стадиона.
Опыт Антона в забегах позволяет ему с высокой точностью отмерять расстояние и пробегать ровно k метров по треку. Но памятью наш бегун похвастаться не может. Единственное, что он в силах запомнить — это сколько кругов он уже пробежал.
Антон предлагает вам скооперироваться, а именно помочь ему узнать длину беговой дорожки стадиона за не более чем 100 продвижений по треку.
Протокол взаимодействия
Взаимодействие происходит с помощью запросов. Вы можете просить Антона пробежать на k метров вперёд с помощью запроса «run k» (1 ≤ k ≤ 109). В ответ на такой запрос вы получите единственное число — количество кругов, которое он уже пробежал, включая текущий запрос. Круг считается завершённым, если бегун пробегает стартовую точку или находится в ней.
Гарантируется, что длина участка — положительное целое число, не превышающее 109.
Если вы готовы указать длину кругового участка, то вы можете убедиться в его правильности с помощью запроса «ensure s». После такого запроса программа должна немедленно завершиться.
При превышении количества запросов (более 100) вы получите вердикт «Wrong answer» (при условии завершения работы программы).
Ваше решение может получить вердикт «Time Limit Exceeded», если вы ничего не выводите или забываете сбросить буфер вывода.
Мне нужен алгоритм решения на C++
#include<iostream>
using namespace std;
int main(){
unsigned long long mid,sumkrug,sum=0,h;
int left=1,right=1000000000,left1,right1;
cout<<"run "<<1000000000<<endl;
sum+=1000000000;
cin>>sumkrug;
Это делается для того чтобы в right1 не было деления на ноль
for(int i=1;i<=9;++i){ уменьшение диапазона проверки (может быть что этого даже не надо)
mid=(left+right)/2;
cout<<"run "<<mid<<endl;
sum+=mid;
cin>>sumkrug;
left1=sum/(sumkrug+1);
right1=sum/sumkrug;
right=min(right,right1);
left=max(left,left1);
}
while(left<right){
mid=(left+right)/2; предполагаемая длина круга
cout<<"run "<<mid<<endl;
sum+=mid;
cin>>sumkrug;
if(sum/mid<sumkrug) если реальных кругов было больше предполагаемого то предполагаемая длина круга больше чем реальная
right=mid-1;
else if(sum/mid==sumkrug){
h=sumkrug;
cout<<"run "<<(sumkrug+1)*mid-sum<<endl;
даёт предполагаемому кругу ровно +1
sum+=(sumkrug+1)*mid-sum;
cin>>sumkrug;
if(sumkrug-h==1) это не может быть sumkrug-j>1 потому что диапазон сведён к минимуму и мид не сможет этого сделать
right=mid;
если реальный круг изменился значит right близок к ответу, потому что если реальная длина круга 989889989 то right может быть 990000000
else if(sumkrug==h) если реальный круг не изменился значит предполагаемая длина круга меньше чем реальная
left=mid+1;
}
else
left=mid+1; если реальных кругов было меньше предполагаемого то предполагаемая длина круга меньше чем реальная
}
cout<<"ensure "<<left;
}
ААА НЕГРЫ