A:从(1,1)移动至(n,m),每次可以往上下左右一个方向移动一次,不能连续两次往同一个方向移动,问是否可行及最少移动次数(solution略)
B:给定n个人和m张椅子(组成环形),每个人要求左右都至少有\(A_i\)的空位不坐人,问是否能将n个人安顿在这m个座位上。
将\(A\)升序排序,贪心构造易得其需要的最少座位数为\(n+A_n+\sum\limits_{i=2}^nA_i\)
/*program from Wolfycz*/
#include
C:给定序列\(A\),和空序列\(B\),每次操作可以让\(B_i+=A_i\),或者\(B_i-=A_i\),问最少需要几次操作可以让\(B\)严格升序?
由于\(n\)较小,故我们可以考虑\(n^2\)做法,暴力枚举一个不动点(即\(B_i=0\)),再从\(i\)位置开始依次确定每个点保证严格升序所需的最小操作次数即可
/*program from Wolfycz*/
#include
D:给定序列\(A\),定义一段区间\([l,r]\)的分值为\(\left\{\begin{aligned}(r-l+1)&,s>0\\0&,s=0\\-(r-l+1)&,s<0\end{aligned}\right.\),其中\(s=\sum\limits_{i=l}^ra_i\),求划分成若干个子段后的最大分值和
我们记\(F[i]\)表示\(1\sim i\)的最大分值,考虑转移:\(F[r]=F[l-1]+(r-(l-1))\),如果\(\sum\limits_{i=l}^ra_i>0\)。如何满足条件?我们将前缀和离散化,用树状数组维护即可。树状数组内存\(F[i]-i\),则每次更新即为\(F[x]=\mathrm{Query}()+x\)。具体见代码
/*program from Wolfycz*/
#include
E:在一个\(n\times m\)的棋盘上放置半皇后,半皇后可以攻击同行同列以及同一主对角线上的所有格子。问最少放置多少个半皇后,可以使所有的格子都至少被一个半皇后攻击到?
构造题。因为半皇后只能攻击主对角线,因此我们考虑将多个半皇后沿反对角线放置。多次试验后可得,将半皇后分为两组,沿反对角线放置在左上和右下角是最优做法。
具体而言,当\(n=3k-1\)时,我们在左上角放置\(k\)个半皇后,在右下角放置\(k-1\)个半皇后即可。对于其他两种情况,我们只随便找个角落,放置1~2个半皇后即可
/*program from Wolfycz*/
#include
F:给定一棵树,若一条边的两端点入度和为偶数,则可将其删去。问是否存在一种删边的顺序,使得所有边都可以被删掉?
对于一个点而言,若其度数为奇,则必定先删除与奇度数点相连的边,然后再为与偶度数点相连的边,依此类推,可知其删边必定是交替存在的。故一个点的所有出边内,要么偶度数与奇度数点相同,要么奇度数点比偶度数点多一。
此外,考虑可以删边的情况,一条边的两个端点度数必定全为奇或者偶,我们记前者为奇边,后者为偶边。我们可以从叶子节点开始,依此确定每条边在删除的时候两端点的奇偶性,并且判断其是否合法。
如果合法,则我们可以从根节点开始递归处理出一条可行的方案,具体可以见代码
/*program from Wolfycz*/
#include