@ 蓝桥杯 练习系统 历届试题 PREV-17
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
闲暇时,福尔摩斯和华生玩一个游戏:
在N张卡片上写有N个整数。两人轮流拿走一张卡片。要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数。例如,某次福尔摩斯拿走的卡片上写着数字“6”,则接下来华生可以拿的数字包括:
1,2,3, 6,12,18,24 …
当轮到某一方拿卡片时,没有满足要求的卡片可选,则该方为输方。
请你利用计算机的优势计算一下,在已知所有卡片上的数字和可选哪些数字的条件下,怎样选择才能保证必胜!
当选多个数字都可以必胜时,输出其中最小的数字。如果无论如何都会输,则输出-1。
输入格式
输入数据为2行。第一行是若干空格分开的整数(每个整数介于1~100间),表示当前剩余的所有卡片。
第二行也是若干空格分开的整数,表示可以选的数字。当然,第二行的数字必须完全包含在第一行的数字中。
输出格式
程序则输出必胜的招法!!
测试样例1
in:
2 3 6
3 6
out:
3
测试样例2
in:
1 2 2 3 3 4 5
3 4 5
out:
4
AC code:
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
static boolean[] marked;
static List<Integer>[] table;
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer in = new StringTokenizer(reader.readLine(), " ");
int n = 0, m = 0, a[] = new int[100], b[] = new int[100];
while (in.hasMoreTokens())
a[n++] = Integer.parseInt(in.nextToken());
in = new StringTokenizer(reader.readLine(), " ");
while (in.hasMoreTokens())
b[m++] = Integer.parseInt(in.nextToken());
Arrays.sort(a, 0, n);
Arrays.sort(b, 0, m);
table = new List[n];
marked = new boolean[n];
for (int i = 0; i < n; i++) {
table[i] = new ArrayList();
for (int k = n - 1; k > i; k--)
if (a[k] % a[i] == 0) table[i].add(k);
for (int k = i - 1; k >= 0; k--)
if (a[i] % a[k] == 0) table[i].add(k);
}
for (int k = 0, i = 0; k < m; k++) {
while (a[i] != b[k]) i++;
marked[i] = true;
if (dfs(i)) {
System.out.print(a[i]);
return;
}
marked[i] = false;
}
System.out.print(-1);
}
static boolean dfs(int n) {
for (int v: table[n]) {
if (marked[v]) continue;
marked[v] = true;
boolean flag = dfs(v);
marked[v] = false;
if (flag) return false;
}
return true;
}
}
博弈论
对手的必败态就是我的必胜态