0
点赞
收藏
分享

微信扫一扫

历届试题 约数倍数选卡片

穆熙沐 2022-06-28 阅读 73

问题描述

  闲暇时,福尔摩斯和华生玩一个游戏:

  在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 思路:  思路:直接dfs搜索各种后继状态,抓住博弈的性质:对于必胜状态,必有一个后继状态是必败的,对于必败状态所有后继状态都是必胜的。假设当前选择是必胜态,那么后手的所有选择都必须是P态才行。 和nim游戏一个思想,把图画出来就好理解了,先手保证后手怎么选先手都有获胜的方式,后手保证先手至少先手有一种方式选择才可以保证先手胜,否则先手输 代码如下:

1 #include<bits/stdc++.h>
2 using namespace std;
3 int array[1000];
4 int Aarray[1000];
5 int array1[1000];
6 int t1=0;
7 int t2=0;
8 int s=0;
9 int flag=1;
10 int DFS(int n)
11 {
12 int l;
13 if(s==0 || s%2==0){
14 flag=1;
15 int a=1;
16 for(int i=t1-1;i>=0;i--){
17 l=0;
18 if((n%array[i]==0 || array[i]%n==0) &&Aarray[i]==0 ){
19 l++;
20 Aarray[i]=1;
21 s++;
22 a=DFS(array[i]);
23 s--;
24 Aarray[i]=0;
25 if(a==0){ flag=0; break;}//决策失败
26 }
27 }
28 if(a==0) return flag;
29 if(l==0){
30 return 1;
31 }
32 }else{
33 flag=0;
34 int a=0;
35 for(int i=t1-1;i>=0;i--){
36 l=0;
37 if((n%array[i]==0 || array[i]%n==0) &&Aarray[i]==0){
38 l++;
39 Aarray[i]=1;
40 s++;
41 a=DFS(array[i]);
42 s--;
43 Aarray[i]=0;
44 if(a==1){ flag=1; break;}
45 }
46 }
47 if(a==1) return flag;
48 if(l==0){
49 return 0;
50 }
51 }
52 return flag;
53 }
54 int main()
55 {
56 //ios::sync_with_stdio(0),cin.tie(0);
57 memset(array1,0,sizeof(array1));
58 memset(array,0,sizeof(array));
59 memset(Aarray,0,sizeof(Aarray));
60 int num;
61 char c;
62 while(true){
63 cin >>num;
64 // scanf("%d",num);
65 c=getchar();
66 array[t1++]=num;
67 if(c=='\n') break;
68 }
69 while(true){
70 cin >> num;
71 //scanf("%d",num);
72 c=getchar();
73 array1[t2++]=num;
74 if(c=='\n') break;
75 }
76 int m=0;
77 for(int i=0;i<t2;i++){
78
79 int j;
80 for( j=0;j<t1;j++){
81 if(array[j]==array1[i]){
82 Aarray[j]=1;
83 break;
84 }
85 }
86
87 int aa= DFS(array1[i]);
88 Aarray[j]=0;
89 if(aa==1){
90 cout << array1[i] << endl;
91 break;
92 }else{
93 m++;
94 }
95 }
96 if(m==t2) cout << "-1" << endl;
97 return 0;
98 }

该代码第四第五组测试数据有点超时,网上有用vector降低时间复杂度的,今天状态不好,看以后再改进把。

作者:你的雷哥

本文版权归作者所有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。

举报

相关推荐

0 条评论