26寒假S基础集训
day 1
枚举、搜索
基础知识
例题1
用四根木棒拼成一个三角形,说明有一条边要用两根木棒。
例题2
在线:对于每组数据,处理完后再接收并处理下一组数据。
离线:接收完所有数据,再分批处理。
时间计算方法:维护三个变量 \(y\),\(m\) 和 \(d\) 分别表示年、月、日,处理进位关系,依次判断是否达到上限(月、日的12、28、29、30、31),超过就清零变量并在上一级变量中+1。注意要判断闰年或平年的二月天数。
本题可以使用离线优化,先输入,然后从小到大把询问排序,取出儒略日最大的数,沿路计算就能算出其他的询问结果。具体地:在每次运行中只维护一个儒略日的数轴,在多次询问中使用同一个而不用再次新建数轴等结构。
1582年要特殊处理。可以先以年(400年)为单位跳到1582年1月,再以月份为单位跳到10月,再以日为单位跳。经过5~14日后再回到之前的规律。
启发:把思路变成暴力,再优化。
例题3
二分、倍增
基础知识
例题1
我们希望扣钱最多的那次扣的钱最少。
例题2
对排列进行 \(m\) 次局部排序,最后询问某位置的值。
关于倍增
1<<k表示 \(2\) 的 \(k\) 次方。
int ans=0;
for(int k=30;k>=0;k--)
if(ans+(1<<k)<=n && check(ans+(1<<k))==1)ans+=(1<<k);
一种很诡异的二分(其实是用倍增)做法。
例题3
例题4
位运算小心越界。
分治
分治算法,即分而治之。
基础知识
具体地,分治算法的核心思路为将一道题目拆分为多个彼此相关的逻辑,并将其关联以解决题目。若使用分治解决题目,则应该保证分治可以:
-
分解原问题为结构相同的子问题;
-
分解到某个容易求解的边界之后,进行递归求解;
-
将子问题的解合并成原问题的解。
注意:对于所有符合上述条件的题目,分治算法并不一定是最优解法。如果各子问题是不独立的,则分治法要重复地解公共的子问题,也就做了许多不必要的工作.此时虽然也可用分治法,但一般用动态规划较好。
引例
归并排序是一个分治算法的典型应用。排序这个问题显然可以分解:给一个数组排序等于给该数组的左右两半分别排序,然后合并成一个数组。
伪代码如下:
void merge_sort(一个数组)
{
if(特殊情况)...;
merge_sort(左半个数组);
merge_sort(右半个数组);
merge(左半个数组, 右半个数组);
}
例题1
例题2
贪心
基础知识
例题1
邻项交换法。
浙公网安备 33010602011771号