1. 程式人生 > >算法筆記_184:歷屆試題 約數倍數選卡片(Java)

算法筆記_184:歷屆試題 約數倍數選卡片(Java)

其中 bsp 計算 程序 article test style 沒有 歷屆試題

目錄

1 問題描述

2 解決方案


1 問題描述

問題描述   閑暇時,福爾摩斯和華生玩一個遊戲:
  在N張卡片上寫有N個整數。兩人輪流拿走一張卡片。要求下一個人拿的數字一定是前一個人拿的數字的約數或倍數。例如,某次福爾摩斯拿走的卡片上寫著數字“6”,則接下來華生可以拿的數字包括:
  1,2,3, 6,12,18,24 ....
  當輪到某一方拿卡片時,沒有滿足要求的卡片可選,則該方為輸方。
  請你利用計算機的優勢計算一下,在已知所有卡片上的數字和可選哪些數字的條件下,怎樣選擇才能保證必勝!
  當選多個數字都可以必勝時,輸出其中最小的數字。如果無論如何都會輸,則輸出-1。 輸入格式
  輸入數據為2行。第一行是若幹空格分開的整數(每個整數介於1~100間),表示當前剩余的所有卡片。
  第二行也是若幹空格分開的整數,表示可以選的數字。當然,第二行的數字必須完全包含在第一行的數字中。 輸出格式   程序則輸出必勝的招法!! 樣例輸入 2 3 6
3 6 樣例輸出 3 樣例輸入 1 2 2 3 3 4 5
3 4 5 樣例輸出 4


2 解決方案

技術分享

具體代碼如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public
class Main { public int dfs(int[] numA, ArrayList<Integer>[] listA, int start) { for(int i = listA[start].size() - 1;i >= 0;i--) { if(numA[listA[start].get(i)] > 0) { numA[listA[start].get(i)]--; int t = dfs(numA, listA, listA[start].get(i)); numA[listA[start].get(i)]
++; if(t == -1) return 1; } } return -1; } public void getResult(String A, String B) { int[] numA = new int[105]; @SuppressWarnings("unchecked") ArrayList<Integer>[] listA = new ArrayList[105]; for(int i = 1;i < 105;i++) listA[i] = new ArrayList<Integer>(); ArrayList<Integer> listB = new ArrayList<Integer>(); String[] arrayA = A.split(" "); String[] arrayB = B.split(" "); for(int i = 0;i < arrayA.length;i++) { int a = Integer.valueOf(arrayA[i]); numA[a]++; } for(int i = 1;i <= 100;i++) { if(numA[i] != 0) { numA[i]--; for(int j = 1;j <= 100;j++) if(numA[j] != 0 && (i % j == 0 || j % i == 0)) listA[i].add(j); numA[i]++; } } for(int i = 0;i < arrayB.length;i++) { int b = Integer.valueOf(arrayB[i]); listB.add(b); } Collections.sort(listB); for(int i = 0;i < listB.size();i++) { numA[listB.get(i)]--; int t = dfs(numA, listA, listB.get(i)); numA[listB.get(i)]++; if(t == -1) { System.out.println(listB.get(i)); return; } } System.out.println("-1"); return; } public static void main(String[] args) { Main test = new Main(); Scanner in = new Scanner(System.in); String A = in.nextLine(); String B = in.nextLine(); test.getResult(A, B); } }

參考資料:

1. 藍橋杯歷屆試題——約數倍數選卡片(博弈論+dfs)

算法筆記_184:歷屆試題 約數倍數選卡片(Java)