2021“MINIEYE杯”中国大学生算法设计超级联赛(3)题解
😊 | Powered By HeartFireY | MINIEYE Contest 1 Solution |
D.Game on Plane
Problem Description
Alice and Bob are playing a game. In this game, there are straight lines on the 2D plane. Alice will select exactly
straight lines
among all the
straight lines first, then Bob will draw a straight line
. The penalty of Bob is defined as the number of lines in
that shares at least one common point with
. Note that two overlapping lines also share common points.
Alice wants to maximize the penalty of Bob while Bob wants to minimize it. You will be given these lines, please write a program to predict the penalty of Bob for
if both of the players play optimally.
Input
The first line contains a single integer (
), the number of test cases. For each test case:
The first line contains a single integer (
), denoting the number of straight lines.
Each of the next lines contains four integers
and
(
, denoting a straight line passes both
and
.
will never be coincided with
.
It is guaranteed that the sum of all is at most
.
Output
For each test case, output lines, the
-th (
) of which containing an integer, denoting the penalty of Bob when
.
Solution
😀 算法标签:计算几何 |
要获得尽可能多的交点数,只需要保证穿过尽可能多的斜率不同的直线即可;
要获取尽可能少的交点数,只需要保证找到尽可能多的斜率相同的直线即可。
Alice 为了让 Bob 与尽量多的直线相交,最优策略就是最小化斜率出现次数的最大值,所以不断从每种斜率的直线中各选一种即可。
G.Photoshop Layers
Solution
😀 算法标签:前缀和 |
队友写的,简述一下思路:
首先每个图层有两种情况
- 图层置为当前颜色(“覆盖”)
- 图层置为上一层颜色+当前层颜色(“重叠”)
首先按输入顺序进行扫描,处理出对于每个图层而言左侧第一个"覆盖"的图层,用
表示。然后预处理出前缀和。
则对于每个询问,根据值找到
,剩余的中间部分直接利用前缀和相减求出答案即可。
放个标程。。。
I.Rise in Price
Problem Description
There are cells on a grid, the top-left cell is at
while the bottom-right cell is at
. You start at
and move to
. At any cell
, you can move to
or
, provided that you don’t move out of the grid. Clearly, you will make exactly
When you are at cell , including the starting point
and the destination
, you can take all the
diamonds at this cell, and have a chance to raise the price of each diamond by
dollars. You will sell all the diamonds you have with the final price in the end, and your goal is to choose the optimal path that will maximize your profits. Note that initially the price of each diamond is zero, and you have nothing to sell.
Input
The first line contains a single integer (
), the number of test cases. For each test case:
The first line contains a single integer (
), denoting the size of the grid.
Each of the following lines contains
integers, the
-th line contains
(
), denoting the number of diamonds in each cell.
Each of the following lines contains
integers, the
-th line contains
(
), denoting how much you can raise the price in each cell.
It is guaranteed that all the values of and
are chosen uniformly at random from integers in
. The randomness condition does not apply to the sample test case, but your solution must pass the sample as well.
Output
For each test case, output a single line containing an integer: the maximum number of dollars you can earn by selling diamonds.
Solution
😀 算法标签:启发式搜索 |
带点权双约图束寻路,单图范围100*100,搜索只有两个方向,考虑启发式搜索:首先构造估值函数的计算方式
计算每个点对于答案的贡献:对于当前点而言,起点到当前点路径上的点权和(已走路径)记为,当前点到终点(未走路径)的路径点权和为
(假设路径已经确定),那么当前点的贡献可以表示为
。
但是在实际的路线中,对于已走路径是唯一确定的,而未走路径是不确定的,因此我们可以假设某条可被选的路径所有权值之和为,对于
的最大值(即
最大值)我们可以由
向
进行状态转移(转移时取
)得到,是一个已经确定的值,状态转移方程如下:
我们可以对贡献方程进行变形:,展开可得
,其中变量为
,对
求导或直接由二次方程对称轴可得当贡献取极大值时,
,则
。代入贡献方程:
那么对于每个点可以计算其贡献值,如果贡献值小于已知答案,那么终止搜索;如果贡献值大于已知答案,则继续搜索。
K.Segment Tree with Pruning
Problem Description
Chenjb is struggling with data stucture now. He is trying to solve a problem using segment tree. Chenjb is a freshman in programming contest, and he wrote down the following C/C++ code and ran ‘’’’ to build a standard segment tree on range
:
Chenjb submitted his code, but unfortunately, got MLE (Memory Limit Exceeded). Soon Chenjb realized that his program will new a large quantity of nodes, and he decided to reduce the number of nodes by pruning:
You know, Chenjb is a freshman, so he will try different values of to find the optimal one. You will be given the values of
and
, please tell him the number of nodes that will be generated by his new program.
Input
The first line contains a single integer (
), the number of test cases. For each test case:
The only line contains two integers and
(
), denoting a query.
Output
For each query, print a single line containing an integer, denoting the number of segment tree nodes.
Solution
😀 算法标签:记忆化搜索 |
回想线段树建树过程,容易知道:对于一定长度的区间,线段树所需要的点数是一定的,那么我我们没有必要对所有的区间进行递归计数,而只需要在搜索过程中记录已有长度对应的点数,然后再次遇到该区间长度时直接返回上次记录的值即可。
记忆化方式打map标记即可,用数组不方便。