Problem: ioi10_e
Categories: data structures
Difficulty: easy
Time limit: 1000 ms | Memory limit: 256 MB

A game called Memory is played using $50$ cards. Each card has one of the letters from A to Y (ASCII $65$ to $89$) printed on the face, so that each letter appears on exactly two cards. The cards are shuffled into some random order and dealt face down on the table.

Jack plays the game by turning two cards face up so the letters are visible. For each of the $25$ letters Jack gets a candy from his mother the first time he sees both copies of the letter on the two face up cards. For example, the first time Jack turns over both cards that contain the letter M, he gets a candy. Regardless of whether the letters were equal or not, Jack then turns both cards face down again. The process is repeated until Jack receives $25$ candies — one for each letter.

You are to implement a procedure play that plays the game. Your implementation should call the procedure faceup(C) which is implemented by the grader. $C$ is a number between $1$ and $50$ denoting a particular card you wish to be turned face up. The card $C$ must not currently be face up. faceup(C) returns the character that is printed on the card $C$.

After every second call to faceup, the grader automatically turns both cards face down again.

Your procedure play may only terminate once Jack has received all $25$ candies. It is allowed to make calls to faceup(C) even after the moment when Jack gets the last candy.

The following is one possible sequence of calls your procedure play could make, with explanations.

|  |  |  |
| --- | --- | --- |
| Call | Returned value | Explanation |
| faceup(1) | 'B' | Card $1$ contains B. |
| faceup(7) | 'X' | Card $7$ contains X. The letters are not equal. The grader automatically turns cards $1$ and $7$ face down. |
| faceup(7) | 'X' | Card $7$ contains X. |
| faceup(15) | 'O' | Card $15$ contains O. The letters are not equal. The grader automatically turns cards $7$ and $15$ face down. |
| faceup(50) | 'X' | Card $50$ contains X. |
| faceup(7) | 'X' | Card $7$ contains X. Jack gets his first candy. The grader automatically turns cards $50$ and $7$ face down. |
| faceup(7) | 'X' | Card $7$ contains X. |
| faceup(50) | 'X' | Card $50$ contains X. Equal letters, but Jack gets no candy. The grader automatically turns cards $7$ and $50$ face down. |
| faceup(2) | 'B' | Card $2$ contains B. |
| ... | ... | Some function calls were omitted |
| faceup(1) | 'B' | Card $1$ contains B. |
| faceup(2) | 'B' | Card $2$ contains B. Jack gets his 25th candy. |

Scoring

|  |  |  |
| --- | --- | --- |
| Subtask | Points | Additional Input Constraints |
| 1 | 50 | Implement any strategy that obeys the rules of the game and finishes it within the time limit. For example, there is a simple strategy that always makes exactly $2 \cdot (49+48+...+2+1) = 2450$ calls to faceup(C). |
| 2 | 50 | Implement a strategy that finishes any possible game with at most $100$ calls to faceup(C). |

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

static char card[51];
static int up[2], is_up[51], candy[25], candies, moves;

char faceup(int C){
   int c0, c1;
   if (C < 1 || C > 50 || is_up[C]) {
      exit(92);
   }
   is_up[C] = 1;
   up[moves%2] = C;
   moves++;
   if (moves%2 == 0) {
      c0 = card[ up[0] ] - 'A';
      c1 = card[ up[1] ] - 'A';
      if (c0==c1 && !candy[c0]) {
         candy[c0] = 1;
         ++candies;
      }
      is_up[ up[0] ] = is_up[ up[1] ] = 0;
   }
   return card[C];
}

void playgame(){
   int i;
   for (i=1;i<=50;i++) {
      card[i] = getchar();
   }
   moves = candies = 0;
   play();
   if (candies != 25) {
      exit(91);
   }
}

int main(){
   playgame();
   printf("OK %d\n",moves);
   return 0;
}

memory.cpp: #include "grader.h"
#include "memory.h"

void play() {
   int i;
   char a, b;
   for (i=0; i<10; ++i) {
      a = faceup(42);
      b = faceup(47);
   }
}

grader.h: char faceup(int C);

memory.h: void play();