問題のブルーブリッジカップ・ソリューション - ボールゲームを取る1

タイトル

このボックスには、誰もが、他の人が取るどのように多く見ることができるNボール、A、Bボックスからボールを取るための2つのテイクターンを持って
、我々はまた、ボックス内に残っているどのくらい見ることができますし、2非常にスマートな、間違った判断を行うことはありません。
私たちの大会:
でなければならない箱から取り出し、それぞれのボールの数:1、3、7または8。
ボールを取ったときに当事者がABSTAINに向けることができません!
まず、ボールを取ったボールを取り、その後、テイク完了するまでの側面を交互に。
当事者が敗者の最後のボールを取得することを余儀なくされた(敗者)
メイクのプログラミングは、初期ボールの特定の番号、Aかどうかの勝利のために、両方の誤判定の場合には決定されませんか?
プログラムの実行は、標準入力から得られたデータは、フォーマットは以下のようにされた場合:
まず、整数N(N <100)は、次のnの整数を表します。Nは、ボールの初期数旨の各(整数<10000)ライン、その後整数です。
Aが勝ち負け表すプログラム出力n行、(入力が0である、1勝)。
例えば、ユーザ入力:
4
1
2
10
18である
アプリケーションべき出力:
0
1
1
0

再帰的なソリューション

再帰的な解決策を考える方が簡単です:

f(int n)
  if(n==0) 对方把球取完了,我赢了,return true;
  if(n>=1 && 我取1个,对方一定为负) return true;
  if(n>=3 && 我取3个,对方一定为负) return true;
  if(n>=7 && 我取7个,对方一定为负) return true;
  if(n>=8 && 我取8个,对方一定为负) return true;
  return false;

コード:

  public static boolean pick1(int n){
    if (n==0)
      return true;
    if (n>=1&&!pick1(n-1))
      return true;
    if (n>=3&&!pick1(n-3))
      return true;
    if (n>=7&&!pick1(n-7))
      return true;
    if (n>=8&&!pick1(n-8))
      return true;
    return false;
  }

入力と出力を処理する主な方法:

  public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    int n = scan.nextInt();
    int[] x = new int[n];
    for (int i = 0; i < x.length; i++) {
      x[i] = scan.nextInt();
    }
    scan.close();
    for (int i = 0; i < x.length; i++) {
      System.out.println(pick1(x[i]) ? 1 : 0);
    }
  }

しかし、この解決策は、nが、あまりにも非効率的な、大きい場合は、問題を抱えているダブルカウントアイテムがたくさんあるため。

メモリタイプの再帰

そのような二重計算の一般的な問題、あなたは再帰的なメモリを使用することができます。

  static Map<Integer, Boolean> cache = new HashMap<>();

  /**
   * @param n  代表当前所剩球的个数
   * @return true:我方赢
   */

  static boolean pick2(int n) {
    //对方拿完了,我就赢了
    if (n == 0)
      return true;
    if (cache.get(n) != null)
      return cache.get(n);
    //大于1,我取1,剩下局面(n-1)对方输,则我方赢
    if (n >= 1 && !pick2(n - 1)) {
      cache.put(n, true);
      return true;
    }
    if (n >= 3 && !pick2(n - 3)) {
      cache.put(n, true);
      return true;
    }
    if (n >= 7 && !pick2(n - 7)) {
      cache.put(n, true);
      return true;
    }
    if (n >= 8 && !pick2(n - 8)) {
      cache.put(n, true);
      return true;
    }
    cache.put(n, false);
    return false;
  }

ダイナミックプログラミング

また、あなたはNへの再帰、再帰的なデジタル小型を書くことができます。

f(N) = true | f(N-1)=false或者f(N-3)=false或者f(N-7)=false或者f(N-8)=false
f(N) = false | N=1

コードの場合:

  public static boolean pick(int n) {
    if (n <= 0)
      return false;
    boolean[] state = new boolean[n + 1];
    state[1] = false;

    for (int i = 2; i <= n; i++) {
      boolean flag3;
      if (i - 3 <= 0)
        flag3 = false;
      else
        flag3 = !state[i - 3];

      boolean flag7;
      if (i - 7 <= 0)
        flag7 = false;
      else
        flag7 = !state[i - 7];

      boolean flag8;
      if (i - 8 <= 0)
        flag8 = false;
      else
        flag8 = !state[i - 8];
      //这就是递推式对应的代码
      state[i] = !state[i - 1] || flag3 || flag7 || flag8;
    }
    return state[n];
  }

再帰から一般的な再帰的プロセスを参照する動的プログラミング()DynamicProgrammingを- CSDNブログ

ありますブルーブリッジボウルコーチングビデオがああ

公開された127元の記事 ・が 97個のように勝っ ビュー310 000 +

おすすめ

転載: blog.csdn.net/zhengwei223/article/details/78608596