Problem: ioi10_b
Categories: search, math
Difficulty: hard
Time limit: 2000 ms | Memory limit: 256 MB

Jack and Jill play a game called Hotter, Colder. Jill has a number between $1$ and $N$, and Jack makes repeated attempts to guess it.

Each of Jack's guesses is a number between $1$ and $N$. In response to each guess, Jill answers hotter, colder or same. For Jack's first guess, Jill answers same. For the remaining guesses Jill answers:

* hotter if this guess is closer to Jill's number than his previous guess
* colder if this guess is farther from Jill's number than his previous guess
* same if this guess is neither closer to nor further from Jill's number than his previous guess.

You are to implement a procedure HC(N) that plays Jack's role. This implementation may repeatedly call Guess(G), with $G$ a number between $1$ and $N$. Guess(G) will return $1$ to indicate hotter, $-1$ to indicate colder or $0$ to indicate same. HC(N) must return Jill's number.

As example, assume $N=5$, and Jill has chosen the number $2$. When procedure HC makes the following sequence of calls to Guess, the results in the second column will be returned.

|  |  |  |
| --- | --- | --- |
| Call | Returned value | Explanation |
| Guess(5) | 0 | Same (first call) |
| Guess(3) | 1 | Hotter |
| Guess(4) | -1 | Colder |
| Guess(1) | 1 | Hotter |
| Guess(3) | 0 | Same |

At this point Jack knows the answer, and HC should return $2$. It has taken Jack $5$ guesses to determine Jill's number. You can do better.

Scoring

Subtask 1 [25 points]

HC(N) must call Guess(G) at most $500$ times. There will be at most $125\,250$ calls to HC(N), with N between $1$ and $500$.

Subtask 2 [25 points]

HC(N) must call Guess(G) at most $18$ times. There will be at most $125\,250$ calls to HC(N), with N between $1$ and $500$.

Subtask 3 [25 points]

HC(N) must call Guess(G) at most $16$ times. There will be at most $125\,250$ calls to HC(N), with N between $1$ and $500$.

Subtask 4 [up to 25 points]

Let $W$ be the largest integer, such that $2^W \le 3 N$. For this subtask your solution will score:

* $0$ points, if HC(N) calls Guess(G) $2W$ times or more
* $25\alpha$ points, where $\alpha$ is the largest real number, such that $0 < \alpha < 1$ and HC(N) calls Guess(G) at most $2W-\alpha W$ times,
* 25 points, if HC(N) calls Guess(G) at most $W$ times.

There will be at most $1\,000\,000$ calls to HC(N) with $N$ between $1$ and $500\,000\,000$.

Be sure to initialize any variables used by HC every time it is called.

Interactor / grader files:
grader.cpp: #include "grader.h"
#include "hottercolder.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

static int moves, TT, NN, prev = -1;
int Guess(int x){
   int r;
   if (prev == -1 || abs(x-TT) == abs(prev-TT)) r = 0;
   else if (abs(x-TT) > abs(prev-TT)) r = -1;
   else r = 1;
   prev = x;
   if (x < 1 || x > NN) exit(92);
   moves++;
   return r;
}

int main(){
   int n=0,i,t,OK=0,sub1=0,sub2=0,sub3=0;
   double worst = 999999;
   while (2 == scanf("%d%d",&NN,&TT)) {
      if (NN > n) n = NN;
      prev = -1;
      moves = 0;
      int h = HC(NN);
      if (h != TT) {
         exit(91);
      }
      int W = floor(0.00001+log(3*NN)/log(2));
      double alpha = 2 - (double)moves/W;
      if (alpha < worst) worst = alpha;
       // 1 means failure
      if ( NN <= 500 && moves > 500 ) exit(93);
      if ( NN <= 500 && moves > 18 ) sub2=1; 
      if ( NN <= 500 && moves > 16 ) sub3=1;
      OK++;
   }
   if (!sub1) printf("OK 1\n");
   if (!sub2) printf("OK 2\n");
   if (!sub3) printf("OK 3\n");
   if (worst > 0) printf("OK 4 alpha %0.2lf\n",worst);
   return 0;
}

hottercolder.cpp: #include "grader.h"

int HC(int N){
   int g = Guess(1);
   int h = Guess(N);
   if (g == 0) return N/2;
   if (g < 0) return N/4;
   if (g > 0) return 3*N/4;
}

grader.h: int Guess(int G);

hottercolder.h: int HC(int N);