T1 robo
solution
大模拟。
注意的细节:
-
参数错误有可能是参数的大小不对,也有可能是参数的类型不对如(“FT 0.3”) 。
-
记得记录一下小机器人停机的情况,如果到最后都没有停过机则返回”ERROR”
-
记得出现过停机情况则之后的所有指令全部无视,所以记得全部读入一下别一不小心直接开始读下一组数据了……
-
炮台和车身是独立的(转动的时候互不影响)
T2 expand
solution
算法一
所有菜市位置和小T所在的位置在一条水平直线上。
考虑有部分菜市在小T右边,部分菜市在小T左边。只有两种遍历情况:向左再向右、向右再向左
而在每个点处的、可行的最大体格是确定的,因此直接累加即可。
最终答案在两种情况中选取一个路径更短的或最短路径相同情况下体格和最大的。
算法二
\(s = 0\)
问题转化为求从一个点出发便利 \(p\) 个点的最短路。
考虑用状压表示哪些点没去过,然后寻找一个没去过的点更新。
设 \(f[i][s]\) 表示在第 \(i\) 个点处的最短路。
转移:
\(f[j][s | (1 << j - 1)] = f[i][s] + dis[i][j]\)
\(dis[i][j]\) 表示两点的最短路,这个可以跑 \(p\) 遍 \(BFS\) 处理出来。
复杂度 \(O(nmp + 2^p\times p\times p)\)
算法三
\(p = 1\)
只有一个目标点,因此只用考虑膨胀问题。
在每一个点都会重新膨胀,因此在每个点处的最大膨胀值其实是固定的。
在 \(bfs\) 的时候直接将每个点的膨胀值加入答案即可。
算法四
设 \(g[i][s]\) 表示考虑到第 \(i\) 个点,所选的集合为 \(s\) 的最大价值。
这个直接在更新 \(f\) 的时候更新就好。
T3 birthday
算法一
\(r - l + 1 < 7\)
直接爆搜就好。
算法二
只有操作一
设 \(r - l + 1 = len\)。则子集合方案数为 \(2^{len}\),区间值域为 \([len,len \times v ]\).只要使 \(2 ^ len > len \times v\) ,就保证操作 \(1\) 一定会输出 Yes。 \(2^len > len \times 1000\) 解得 \(len\) 的最小正整数解为 \(14\)。所以当 \(len \geq 14\) ,操作 \(1\) 可以直接输出 Yes。
当 \(len < 14\)。首先会想到像上一个分段一样搜索,但每次搜索复杂度最大为 \(3^{13}\)。考虑采用二分优化,首先搜索完 \([l,mid]\) 内所有集合的可能值域,再去搜索 \([mid + 1,r]\) 一旦发现得到的某个值在之前出现过, 即可直接结束搜索。 当然如果两个搜索区间内搜索到值为 \(0\) 也可提前结束搜索。
每次搜索复杂度最坏为 \(3^6 + 3^7\)
算法三
对于操作 \(2\),考虑用线段树 \(lazy-tag\) 实现区间修改。
区间幂不好区间修改,但考虑到每次最多调用 \(13\) 个数,可以下放到叶子节点时才释放 \(lazy\) 标记。
\(lazy\) 标记释放时,快速乘或暴力修改常数是巨大的。发现 \(b[i]\) 值域在 \([0,v - 1]\),可以提前处理好 \([0 ,v - 1]\) 的幂的表格,用倍增实现。
\(f[i][0] = i \times 3 \% v,f[i][j] = f[f[i][j - 1]][j - 1]\)。