题目大意:
给你一个数,你可以交换这个数任意两位,可以交换k次。但是不能出现前导0。求经过k次操作可以形成的最大值和最小值。这个数小于20位。
解题思路:
首先,需要先解决这样一个问题:给定一个原序列,再给出它经过几次变换的序列,能不能求出, 原序列最少经过了几次交换,成为了新的序列。 不妨假设原序列的为 1,2,3….n。(如果是其他情况,完全可以建一个下标数组b,让它记录这一位现在是原来数组的第几位数)
假设交换了2号位和3号位,那么让b[2]=3,b[3]=2。又交换了3号位和5号位。那么就有b[5]=2,b[3]=5。至于怎么看交换了几次,我们可以看b[i]是不是i,如果不是,就说明这一位已经被交换了,那么就去查看b[i],看这一位被换成了谁,就可以一直查询下去了。
具体怎么做呢,建立vis数组,表示第 i 是否被查询过,每次遇到b[i]不等于 i 的时候,就去继续查询b[i]位。
1 | inline bool check(int n) |
解决了上述问题,那么就好办了,因为最多20位,所以可以直接全排列每一位,判断是否可在k次交换以内完成,然后计算其大小,统计答案即可。
而algorith库已经给我们提供了一个全排列函数,next_permutation,它会检测是否可进行下一次排序(从升序到降序,如果可以,则会把数组变到下一个排列,并返回true,如果不能,则直接返回false),于之类似的有prev_permutation,它是从降序到升序。
代码:
1 |
|
最后送大家一个可爱的安柏
每日中二
有了自己的信仰,孤独就不再可怕。
- 本文作者: 水蓝络合物
- 本文链接: https://miku39393939.github.io/2021/01/15/2021-01-15-HDU6351/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!