T1: CITYWALK
简化题意
求两个 o 字符之间的最短路径。
解题思路
可以把问题转化为:求两个 o 字符之间的曼哈顿距离。首先得到两个o在二维字符数组中的下标,然后用距离公式 d(A,B)=∣x1−x2∣+∣y1−y2∣d(A,B)=\left| x_1-x_2 \right|+\left| y_1-y_2 \right|d(A,B)=∣x1 −x2 ∣+∣y1 −y2 ∣ 即可快速求出问题的解。
个人代码
T2: 集合操作
简化题意
给定集合 SSS,按照输入数据对 SSS 进行一系列操作。
解题思路
用 STL 中的 unordered_map 代替集合进行运算,统计每个数在集合中的出现次数。这个时候难点就出在了操作 222 上。
操作 222 解决方法:首先是最基础的,把 xxx 的出现次数减 ccc 或者变为 000(等价于m[x]-=min(y,m[x])),如果 xxx 的出现次数清零了,那么就要重新更新最大值和最小值了,所以要将其余出现在集合里的数都给遍历一遍,涉及到了map的遍历方法。map 的遍历方法就需要用一种新的关键字auto,感兴趣的可以自行搜索学习。
个人代码
T3: 乌尔达哈城市分布图
简化题意
给定一张无向图,输出每个点只通过一条边可以到达的点的数量,并按顺序输出编号
解题思路
简单题,考察建图,我用邻接表建图。
个人代码
T4 恰好
简化题意
求有多少组连续的数之和为 NNN。
解题思路
这题比较毒瘤,对数学底子差的人不友好。另外这题有点类似于洛谷的这道题。
说说推法:
不妨先推出不含 000 和负数的连续正整数数列之和等于 NNN 的情况。
题目让我们求
N=∑i=lriN= \sum_{i = l}^{r} {i} N=i=l∑r i
用小学学过的高斯求和公式可以推出,上面的式子可得
N=(l+r)(r−l+1)22N=(l+r)(r−l+1)\begin{aligned} N &= \frac{(l+r)(r-l+1)}{2}\\ 2N &= (l+r)(r-l+1)\\ \end{aligned} N2N =2(l+r)(r−l+1) =(l+r)(r−l+1)
为了方便,我们直接把 NNN 赋值为 2N2N2N
枚举数列项数由于公差为 111 ,可知项数不会大于 lll 与 rrr 的和,所以枚举到 2N\sqrt{ 2N }2N 就行了,再多就超时了。
设枚举用的变量为 iii。判断时首先要满足 N∣iN\mid iN∣i,因为 iii 是项数,可得 Ni\frac{N}{i}iN 是首项与末项之和,而首项与末项一定为整数,所以 Ni\frac{N}{i}iN 一定为整数,所以 N∣iN\mid iN∣i 这个条件必须成立才能进行下面的判断。
当以上条件成立后,首项与末项的差就是 i−1i-1i−1,然后就变成了一个和差问题(不会的请重修小学),可得
sum=l+r=Nir=sum−i+12l=sum+i−12\begin{aligned} sum=l+r= \frac{N}{i}\\ r= \frac{sum-i+1}{2}\\ l= \frac{sum+i-1}{2} \end{aligned} sum=l+r=iN r=2sum−i+1 l=2sum+i−1
接下来就是判断,然后统计答案。当 lll 和 rrr 满足 r∣2r \mid 2r∣2 且 l2≤N2\frac{l}{2} \le \frac{N}{2}2l ≤2N 时就是一个合法的答案。
最后不要忘记将答案乘 222 再输出,因为数列中还可以包含负数和 000。
个人代码
T5:符文锁
简化题意
求有多少种组合方法满足以下条件。
解题思路
?这不就是ABC356C吗?代码改都不用改。
题目中可得 N≤15N \le 15N≤15 ,范围极小,可以直接暴力 dfs 拆解,枚举每一个钥匙是否选择,选完后对这种方法进行查验,如果合法则统计答案。最后输出统计出来的答案数。
CHECKCHECKCHECK 函数的写法(用于判断序列的合法性)
遍历每种试过的方法,如果这个数字曾经试过,则统计下来。当这个试过的情况统计完后,如果这个情况的结果是 o 则判断统计下来的总数,如果小于 mmm 则直接否定,因为可能另外没有被选到的数是正确的,否则继续遍历下一个试过的情况。 如果这个情况的结果是 x 则判断统计下来的总数,如果大于等于 mmm 则直接否定,因为把正确和不正确的数全都选下来了。
判断完后不要忘记返回 true 或 1
DFSDFSDFS 的写法
设置 222 个参数,一个代表是否选择这个数(numnumnum),一个代表这是第几个数(stepstepstep)。当函数被调用时,首先给 stepstepstep 标记为 numnumnum 代表这个数 stepstepstep 是否已被选用。如果所有数都选完了,则判断这个数是否合法(调用 checkcheckcheck),合法则统计。这个时候继续往下搜索,调用时 stepstepstep 要 +1+1+1 代表继续搜索下一个数,numnumnum 需要分为两种情况搜索,就是为 111(选择下一个数) 和为 000(不选择下一个数) 的情况。
组合进 MAINMAINMAIN 主函数
最后组合起来,读入后调用函数 dfs(0,0) 最后输出答案就行了。
个人代码
T6:集合操作2
简化题意
每次输入会输入一些指令,你需要按照指令去严格进行操作。
解题思路
其实这题最烦的地方就是操作类型 111,但是只会将所有元素都赋值为 xxx ,我们可以建一个数组(visvisvis),去记录这个数在被进行 111 操作后是否被修改,增大了多少数值,而 xxx 可以再建一个变量储存。进行 111 操作时需要将 visvisvis 清空,每次全清空会 TLE,所以还要建一个新数组(xiaxiaxia),存储被修改的值。进行操作 222 时,加减的操作直接在 visvisvis 里进行,不要忘记在 xiaxiaxia 里记录。进行 333 操作时就无需多言了,进行简单处理后就可以输出了。当然,还需要建立一个布尔类型 flagflagflag 记录在输入 AAA
后是否进行了 111 操作,如果进行了,则设为 000,否则为 111,最后只需要在 333 操作时输出 vis[y]+num+flag*a[y] 就行了。
个人代码
感谢观看
如果对你有帮助的话,就请给我点一个赞呗(无耻地说出这句话),感谢大家的喜欢!