Problem:
探索

「探索」とは、たくさんの情報の中から望みの情報を得る操作のことです。身近な例では、合格発表の時の「たくさんの受験番号から自分の受験番号を見つける」ことや、電話帳から「会津太郎さんの電話番号を見つける」ときなどがあります。この探索という操作はコンピュータの分野でも広く用いられています。

探索の方法は沢山あります。探索の対象となるデータが、小さい順(または大きい順)に並べられている場合に使うことができる探索の方法を考えます。

小さい順(または大きい順)に並べられているデータ列の中央に位置する値と目的の値との大小関係を用いて、中央に位置する値から前半部分を探索範囲にするか後半部分を探索範囲にするかを決めることで、探索の範囲を絞っていく方法があります。手順は以下のようになります。

データの列の全体を探索の範囲とします。

探索の範囲の中央に位置する値を調べます。

目的の値と中央に位置する値が一致すれば探索を終了します。

目的の値と中央に位置する値よりも小さければ前半部分を探索の範囲とし、大きければ後半部分を探索の範囲として2.へ戻ります。

以下は上述した探索の方法の例です。この例での目的の値は51です。それぞれのデータには番号
(index)が振られており、この番号は0から始まっています。

ステップ1: 最初は番号0~6全体を探索の範囲とします。

ステップ2: 探索の範囲の中央に位置する値を調べます。ただし、「中央に位置する値」とは、(左側の番号+右側の番号)を2で割った番号の位置にある値とします。つまり、この場合、(0 + 6) ÷ 2 を計算し、番号3にある値(36)が中央に位置する値となります。

ステップ3:目的の値(51)と中央に位置する値(36)を比較します。

ステップ4:ステップ3の結果から、目的の値は中央に位置する値より大きいので、後半部分にあたる番号4 (中央に位置する値の隣)以降を探索の範囲とします。同様の手順で探索の範囲の中央に位置する値を調べ、目的の値が中央に位置する値より小さければ前半部分を探索の範囲とし、大きければ後半部分を探索の範囲として、探索の範囲を小さくしていきます。(ステップ2~ステップ4の繰り返し)目的の値が中央に位置する値と一致するか、探索の範囲がつきてしまった時に探索を終了します。

n 個の数値の配列を入力とし、目的の値と中央に位置する値を比較した回数を出力するプログラムを作成してください。ただし、中央に位置する値の番号を計算したとき、割り切れない場合は、小数点以下を切り捨てた値をその番号とすることとします。
与えられるデータ列は小さい順に整列されているものとします。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されます。 各データセットは以下の形式で与えられます。

n
a1
a2
:
an
k

1 行目に数値の数 n (1 ≤ n ≤ 100) 、続く n 行に i 個目の数値 ai (1 ≤ ai ≤ 100000, 整数) が与えられます。

続く行に探索する値 k (1 ≤ k ≤ 100000) が与えられます。

Output

データセット毎に探索が終わるまでの比較回数を１行に出力します。

Sample Input

7
11
15
23
36
51
61
86
51
4
1
2
3
5
4
0

Output for the Sample Input

3
3

Solution in C# (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _0188
{
    public class Program

    {
        public static void Main(string[] args)
        {
            while (true)
            {
                int n = RInt(); if (n == 0) break;
                int[] nums = new int[n];
                for (int i = 0 ; i < n ; i++)
                {
                    nums[i] = RInt();
                }

                int target = RInt();

                int cnt = 1;
                int left = 0;
                int right = n;

                while (right - left > 0)
                {
                    cnt++;
                    int mid = (left + right) / 2;
                    if (nums[mid] == target) break;
                    else if (nums[mid] < target) left = mid + 1;
                    else right = mid - 1;             
                }

                Console.WriteLine(cnt);

            }
        }

        static string RSt() { return Console.ReadLine(); }
        static int RInt() { return int.Parse(Console.ReadLine().Trim()); }
        static long RLong() { return long.Parse(Console.ReadLine().Trim()); }
        static double RDouble() { return double.Parse(Console.ReadLine()); }
        static string[] RStAr(char sep = ' ') { return Console.ReadLine().Trim().Split(sep); }
        static int[] RIntAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Trim().Split(sep), e => int.Parse(e)); }
        static long[] RLongAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Trim().Split(sep), e => long.Parse(e)); }
        static double[] RDoubleAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Trim().Split(sep), e => double.Parse(e)); }
        static string WAr<T>(IEnumerable<T> array, string sep = " ") { return string.Join(sep, array.Select(x => x.ToString()).ToArray()); }
    }

}