FZU 2111 的一点思考

 感觉题目有点问题,作一点探讨,有问题的地方欢迎指出。

解答1:

解答2出自博客:(详细代码略)

http://blog.csdn.net/castledrv/article/details/45200805

考虑如下一组测试数据

97865432111 3

虽然都是AC代码,但是两者出现了截然不同的输出

解答1输出  11165432879

解答2输出  11165432978

这种情况作为一道正式比赛题目(“高教社杯”第三届福建省大学生程序设计竞赛)是不可理解的。

首先按照题目意思来解释这个测试数据:

原始数字串为97865432111,最多进行3次操作,我们可以任意选取满足条件$1≤i<j≤11$的$i,j$(假定下标从1开始),对其进行交换,以满足目标数字串最小。

很显然,我们可以将第1位9和最后一位1($i=1,j=11$)交换得到17865432119,

再将第2位的7和倒数第三位的1($i=2,j=9$)交换得到11865432719,

最后将第三位的8与倒数第二位的1($i=3,j=10$)交换,得到11165432789,这应该是最小的数。

这里使用贪心策略时,很显然要保证开始的数位是最小的;因此我们让$i$从0递增,每次选取串中最小的元素$a[r]∈A$,将其与$a[i]$进行交换。问题在于,如果存在着$t$个重复的元素$a[r_1]=a[r_2]=...=a[r_t]=min{a[1],a[2],...,a[n]}$(这里设$r_n$是递增的),究竟应该将其与哪一个交换?这两个AC的程序显然没有做出回答。解答1将其与倒序的,也就是$r_t$交换,而解答2将其与正序的,也就是$r_1$交换。事实上,具体应该交换的次序,取决于$r_k(1≤k≤t)$的位置。设需要交换的数为$a[i_1]<a[i_2]<...<a[i_s]$(设$i_n$也是递增的,$s≤t$),那么$a[i_1]$应该和$a[r_1]$交换,$a[i_2]$应该和$a[r_2]$交换,以此类推。这样才能够保证,整个输出的数是最小的。若$s>t$,则需要考虑与其相比次小的元素进行相应的操作。

在上面两种解答中,无论是从正向还是反向,都不能保证交换后是最小的。看了VJUDGE的LEADERBOARD的好几份代码,都没考虑到最小值重复的问题,题目数据给出$n_{max}=1000$,$a[i]∈{0,1,2,3,4,5,6,7,8,9}$,怎么可能没有重合的最小值?

原文地址:https://www.cnblogs.com/ggggg63/p/6910495.html