最近在系统学习Python的知识,学完排序之后,遇到了一个排序的具体问题,问题具体描述如下:
时间限制:1000ms
空间限制:5000K
输入一行 k
个用空格分隔开的整数,依次为 n1,
n2 … nk。请将所有下标不能被
3 但可以被 2
整除的数在这些数字原有的位置上进行升序排列,此外,将余下下标能被 3 整除的数在这些数字原有的位置上进行降序排列。
输出包括一行,与输入相对应的若干个整数,为排序后的结果,整数之间用空格分隔。
样例1
输入:
1 5 4 3 10 7 19
输出:
1 3 7 5 10 4 19
提示信息
请注意,题面中的下标是从 1
开始的哦!
这道题其实本身很简单,按照要求,把对应位置上的需要升序的数据取出,然后把对应位置上的需要降序的数据取出,分别排序就可以完成了,这样的代码,写起来有点繁琐,但是是最快的算法,有时候代码繁琐,运算快速也不失是一种选择。
但是,与此同时,我在探索简洁的代码解决此问题的方法,首先想到的是给出排序的准则,进行定制型的排序,Python的sort函数是可以指定排序准则函数的,sort函数,第一个参数指定排序的对象,第二个参数,即可给出排序的准则。
对于这道题的排序准则,分别三条,首先是下标不能被3整除,但是能被2整除的数据,排序准则为从小到大;其次是下标能被3整除的数据,排序准则为从大到小;最后是剩下的其余数据,保持不动,描述保持原位置的排序准则,其实就是按照其下标大小进行排序。
确定这样的三条排序准则后,在代码中写出来即可,但是问题是sort函数用comp进行排序,是得不到正确答案的,原因是sort里面的算法封装的是适用于普遍的排序的算法,对于一般的排序,其问题满足自反性,对称性和传递性。但是,显然上面描述的问题,并不满足传递性。因为比如分别选择下标是2,4,5的数字,加入首先有偏序对(2,4)∈R,同时有(2,5)∈R,因为2,4的下标的需要看数据(属于不能整除3,并且能被2整除的),2,5的下标直接比较下标,但是这时候显然对于偏序对(5,4)不属于这个关系(这里要(4,5)就对了)。
因此不能直接使用已封装的sort,那么对于这种的问题,需要采用两两逐对比较的方式,采用类似冒泡的排序算法就可以解决这个问题了,但是其时间复杂度由原来的小于O(nlogn)上升到了O(n*n),好处就是代码整洁,不冗长,这里就需要自己衡量具体问题中到底使用哪种算法了。
附上AC的代码:
#coding=utf-8
def comp(
a, b ):
if( a[ 1 ] % 3 != 0 and b[ 1 ] % 3 != 0 ):
if( a[ 1 ] % 2 == 0 and b[ 1 ] % 2 == 0 ):
return
a[ 0 ] > b[ 0 ]
#end if
#end if
elif( a[ 1 ] % 3 == 0 and b[ 1 ] % 3 == 0 ):
return a[ 0 ] < b[ 0 ]
#end elif
return a[ 1 ] > b[ 1 ]
#end
comp
input_s =
raw_input()
input_s =
input_s.split( ' ' )
input_int
= []
for i in
range( len( input_s ) ):
input_int.append( ( int( input_s[ i ] ), i + 1 ) )
#end
for
for i in
range( len( input_int ) ):
for j in
range( i + 1, len( input_int ), 1 ):
if( comp( input_int[ i ], input_int[ j ] ) ):
temp
= input_int[ i ][ 0 ];
input_int[ i ] = ( input_int[ j ][ 0 ], input_int[ i ][ 1 ]
)
input_int[ j ] = ( temp, input_int[ j ][ 1 ] )
#end if
#end
for
#输出
for i in
range( len( input_s ) - 1 ):
print input_int[ i ][ 0 ],
#end
for