第16届蓝桥杯备赛

第一题

异或运算

(1)^=//是按位异或赋值运算符。相同位得0,不同位得1.a=2,b=1,c=a^b;c=3;

(2)注意:每次操作时都可以选择对Alice或者 Bob操作。无论操作的人是谁。

(3)思路:最终结果的判断从二进制的高位开始。高位为1者胜。每次异或,只观察翻转的从高到

低的某一位。异或的特征:0和a异或为a,1和a异或a翻转。本题就属于博弈论的问题。

(4)博弈论的特征:回合制;有限步终止;胜负由最后一步决定。

//翻转次数是n的个数;每次翻转看的是有效的最高位【偶数个1跳过】。

(5)思路:考虑必胜和必败的两种情况。

1.计算每个数字高位到低位的1的个数和;

2.分类:如果最高位只有一个1,A可以用1翻转得到1,最终状态保持(1,0);

如果最高位有偶数个1,可知平局;

如果最高位有奇数个1,A,(1,0),B如果操作A,(0,0),最终达到的局面:A先手,(0,0),奇数个1;

B如果操作B,(1,1),最终达到局面:A先手,(1,1),奇数个1。可想而知,A获胜,总共需要奇数轮。

若是偶数轮:翻奇数次的前一次就是B胜。不过不严谨。不如通过特例好了。

(6)代码:取每个数的二进制位并且存到数组:x&1,x>>=1(x=x>>1),数组下标用计数器。

循环遍历数组,当遍历结束奇数个1的位,则平局。

第二题

DFS

//受伤的皇后

回溯+剪枝

(1)不同行。所以dfs一行行地搜。int col[n],存储当前行的列。

(2)dfs:Q:当前递归分支什么时候结束A:n个皇后放好。或者某一行(当前递归的这一层)没有

符合条件的列//这种情况,递归函数会自然结束当前分支的执行。Q:回溯指的是什么?A:代码:dfs()之后将

之前放置的位清零;执行:当前递归分支结束,会从上一个分支开始执行。Q:而回溯怎么保证和之前走的路径不一样呢?A:通过循环控制。(回溯后,循环变量 c 会从上次失败的位置继续递增,直到 c > n 时结束循环)。Q:return的作用?A:终止当前分支,返回到上一次调用栈。

(3)dfs:满足条件的判断{答案处理;return};循环{设置已经处理,dfs(),重新置于未处理;}

第三题

处理一个数中的每个数字

题目:1~2020中有多少个字符2?

回答:枚举1~2020;对每个数的每一位进行判断【重点:while(n)if(n%10==2)cnt+=1;n/=10;】n/10将一个十进制数不断右移1位,n%10,取一个数的最低位。【取低4位,n%10的四次方】

第四题

数列求值

【注意】开longlong 仍旧会溢出。那么最后的方法:求低四位,在加法的过程中,取模取低四位,得到正确结果。

第五题

最大降雨量

【一道神奇的题】:7行7列,每行的中位数代表该行,最后的结果在7行里面取中位数。

题解:在方格7*7中,按照图形的大小找中心点。然后发现在第4行第4列是要求的位置。为了满足它最大+中位数。以它为顶点的左下角的方格中的数必须大于它。(表述不准确,但大概是这个意思。4*3+3)49-15=34.

第六题

外卖店优先级【虽然我始终觉得应该可以模拟出来···】

第七题

并查集

//修改数组

(1)直接模拟:数据结构选择string。无法模拟数组中的两位数;

选择unordered_set s;//存的是数组啊,不去重。可以

用.count()代替.find()。会超时;

(2)当合并/查询操作次数极高时,需要用路径压缩进行优化。这里频繁查找一个数字在之前有没有出现过;

如果出现过,就加1;再查找它加1后有没有出现过;这样的话,构建的树:按连续的数字构建,其中较大的节点

是较小的父节点。经过路径压缩。它们会直接指向最大的父节点。//注意:读入一个数,造成两个数的合并。

(3)代码:find(x)的代码就能找到出现的相同的数的祖先节点。p[i]=i;//保存的父节点。不是父节点的编号是父节点的值。x也是节点的值不是节点的编号。

第八题

状态压缩DP

“很好哇,今天的第二道状压”

(1)卡点:没有办法把每包糖果中的口味状态用二进制表示出来。为什么呢?原因一:我以为题目输入

的整数是随机的。实际应该不是。比如第一包:1,3,5(表示第1,3,5种口味);原因二:左移的使用。

第1种映射到二进制是第一位为1,那就是1左移0位。因为二进制的第一位不要移动啦。如果是x就是左移x-1位;

然后我们怎么把这些1放在一个二进制数组呢?a[i]|=1<<(x-1);

(2)卡点:dp怎么得到最小。首先要建立起遍历子集合的概念。dp数组:得到当前糖果口味所需要的最小包数。

外层循环:遍历每颗糖果;内层循环:遍历所有的口味的子集合。判断:(1)方法数不大于n;(2)当前子集合+

这包糖果的口味的口味状态的dp值等于它本来的dp,从dp[j]+1转移而来的dp值之间的min。

自然最后[1<

状压的总结:

(1)dp:两层循环。遍历所有状态+遍历影响状态的单元。

(2)细节:二进制左移k位,末尾是k+1位。而它是从0开始计数的。dp[mask][j].如果j从0开始算第一个节点,

那么遍历影响状态的单元的时候一开始就从0开始编号。【虽然题目很可能是从1开始】。

分数的输出只能实现3/2.不用实现上下结构

你可能感兴趣的:(算法,深度优先,蓝桥杯)