蓝桥杯 约数倍数选卡片

思路:

搜索、博弈论。

实现的时候一个剪枝是从较大的数开始选,因为较大的数约数或倍数少一些,搜索的层数少。

还可以预处理出每个数的约数和倍数,这样搜索的时候不用扫描所有的数。

实现:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <string>
 5 #include <cstring>
 6 #include <sstream>
 7 #include <vector>
 8 #include <algorithm>
 9 using namespace std;
10
11 const int MAXN = 105;
12 int a[MAXN], b[MAXN], m = 0;
13 vector<int> ok[MAXN];
14
15 bool check(int x, int y)
16 {
17     int p = min(x, y);
18     int q = max(x, y);
19     return !(q % p);
20 }
21
22 void init()
23 {
24     for (int i = 1; i < MAXN; i++)
25     {
26         if (a[i])
27         {
28             for (int j = 1; j < MAXN; j++)
29             {
30                 if (a[j] && check(i, j))
31                     ok[i].push_back(j);
32             }
33         }
34     }
35 }
36
37 bool dfs(int last)
38 {
39     for (int i = ok[last].size() - 1; i >= 0; i--)
40     {
41         int tmp = ok[last][i];
42         if (a[tmp])
43         {
44             a[tmp]--;
45             bool res = dfs(tmp);
46             a[tmp]++;
47             if (!res)
48                 return true;
49         }
50     }
51     return false;
52 }
53
54 int main()
55 {
56     string x;
57     int t;
58     stringstream s;
59     getline(cin, x);
60     s << x;
61     while (s >> t)  a[t]++;
62     init();
63     s.clear();
64     getline(cin, x);
65     s << x;
66     while (s >> b[m++]);
67     m--;
68     sort(b, b + m);
69     int * end = unique(b, b + m);
70     bool flag = true;
71     for (int i = 0; i < end - b; i++)
72     {
73         a[b[i]]--;
74         bool res = dfs(b[i]);
75         a[b[i]]++;
76         if (!res)
77         {
78             cout << b[i] << endl;
79             flag = false;
80             break;
81         }
82     }
83     if (flag)
84         cout << -1 << endl;
85     return 0;
86 }

总结:

必败点:前一个选手将取胜的位置称为必败点。

必胜点:下一个选手将取胜的位置称为必胜点。

必胜点和必败点属性:

(1)所有终结点是必败点。

(2)从任何必胜点操作,至少有一种方法可以进入必败点。

(3)无论如何操作,从必败点都只能进入必胜点。

可以采用递归或递推实现。

注意函数参数的值传递的过程。

回溯的时候不要影响标记状态的全局变量,要及时归位。

时间: 2024-10-18 15:26:30

蓝桥杯 约数倍数选卡片的相关文章

蓝桥杯 历届试题 约数倍数选卡片 求大神指点 首先声明,我的代码有问题!不喜勿进,若有意向,可以讨论,我百度不到这道题的题解

历届试题 约数倍数选卡片 时间限制:1.0s   内存限制:256.0MB 问题描述 闲暇时,福尔摩斯和华生玩一个游戏: 在N张卡片上写有N个整数.两人轮流拿走一张卡片.要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数.例如,某次福尔摩斯拿走的卡片上写着数字"6",则接下来华生可以拿的数字包括: 1,2,3, 6,12,18,24 .... 当轮到某一方拿卡片时,没有满足要求的卡片可选,则该方为输方. 请你利用计算机的优势计算一下,在已知所有卡片上的数字和可选哪些数字的条件下,怎

蓝桥历年套题 约数倍数选卡片 博弈

标题:约数倍数选卡片 闲暇时,福尔摩斯和华生玩一个游戏: 在N张卡片上写有N个整数.两人轮流拿走一张卡片.要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数.例如,某次福尔摩斯拿走的卡片上写着数字“6”,则接下来华生可以拿的数字包括: 1,2,3, 6,12,18,24 .... 当轮到某一方拿卡片时,没有满足要求的卡片可选,则该方为输方. 请你利用计算机的优势计算一下,在已知所有卡片上的数字和可选哪些数字的条件下,怎样选择才能保证必胜! 当选多个数字都可以必胜时,输出其中最小的数字.如果无

算法笔记_184:历届试题 约数倍数选卡片(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 闲暇时,福尔摩斯和华生玩一个游戏: 在N张卡片上写有N个整数.两人轮流拿走一张卡片.要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数.例如,某次福尔摩斯拿走的卡片上写着数字"6",则接下来华生可以拿的数字包括: 1,2,3, 6,12,18,24 .... 当轮到某一方拿卡片时,没有满足要求的卡片可选,则该方为输方. 请你利用计算机的优势计算一下,在已知所有卡片上的数字和可选哪些数字的条件下,怎样选择才能保证必胜! 当

算法-蓝桥杯习题(六)

蓝桥杯习题 蓝桥杯练习系统习题加答案,总共分为6部分,90%习题使用C语言解答,部分使用C++或者Java.大部分习题为搜索参考或者别人提供所得,不足之处在所难免,恳请批评指正(预计200多题,习题仅供学习交流) 目录 算法训练(详见 算法-蓝桥杯习题(一))Go 算法训练(详见 算法-蓝桥杯习题(二))Go 算法提高(waiting...) 历届试题(详见 算法-蓝桥杯习题(六))Go 历届试题(详见 算法-蓝桥杯习题(七))Go 蓝桥杯练习系统评测数据 链接: http://pan.baid

蓝桥杯练习系统题解

转于:http://www.cnblogs.com/cshhr/p/3550014.html 蓝桥杯官网练习系统题解(非VIP) BEGIN-4(Fibonacci数列) 有递推公式,大家都知道用递推公式求,仅仅要记得在递推的时候同一时候取模求好 这里给一份另类代码,用矩阵高速幂求,事实上还有循环节 /* (1 1) * (Fn-1) = ( Fn )//矩阵相乘,将就着看吧 (1 0) (Fn-2) (Fn-1) (1 1) * (1 1) * (Fn-2) = ( Fn ) (1 0) (1

第七届蓝桥杯C语言C组-(自己懂的题目)

第七届蓝桥杯C语言C组-(自己懂的题目) 表示刚刚查了成绩,省赛一等奖,有资格去北京了,然后写一下总结, 先来写一下我懂的题目,毕竟我也是菜鸟,听说国赛比预赛难几个等级... 第一题 报纸页数 X星球日报和我们地球的城市早报是一样的, 都是一些单独的纸张叠在一起而已.每张纸印有4版. 比如,某张报纸包含的4页是:5,6,11,12, 可以确定它应该是最上边的第2张报纸. 我们在太空中捡到了一张X星球的报纸,4个页码分别是: 1125,1126,1727,1728 请你计算这份报纸一共多少页(也就

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共

蓝桥杯 安慰奶牛

算法训练 安慰奶牛 时间限制:1.0s   内存限制:256.0MB 锦囊1 使用最小生成树算法. 锦囊2 将每条边(a, b)的权值Lj改变为2Lj+Ca+Cb,然后使用最小生成树来计算. 问题描述 Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路.道路被用来连接N个牧场,牧场被连续地编号为1到N.每一个牧场都是一个奶牛的家.FJ计划除去P条道路中尽可能多的道路,但是还要保持牧场之间 的连通性.你首先要决定那些道路是需要保留的N-1条道路.第j条双向道路连接了牧场Sj和

蓝桥杯总结

蓝桥杯今天出来成绩了,看到了自己考试完之后期望的成绩!省三!!!考完之后瞬间感觉这次惨的不行了,第二题都搞错了,觉得简单,就直接手算了,结果就搞错了.简直就是没对的啊,这次考试之前,老想着好好考,结果生怕读错题,因为我读题的速度特别慢,不仅慢而且容易读错.所以怕读错,越这样越完蛋,结果第一题就读了好几遍.然后才开始写代码.刚开始还做错了,还好后来及时发现过来,极度不自信导致的!这种大考试心态问题太重要了,越怕出错越错,放轻松,当做平时做题就好.后面一个加号变乘号的题竟然看错了.今天同学给我说是两