這道題是Round 1B 2010的第二道題,第一次看的時候,沒看懂題目意思,這一次總算是把題目看懂了。看懂之後,才發現,原來如此簡單。
先說一下題目意思,在一條非常narrow的路上,有一群chicks,以各自的速度朝Barn前進。如果後面一隻撞上前面的一隻,就要以前面一隻的速度前進。現在有一個arm of crane,機械臂,可以瞬間交換兩隻chick的位置,如果一隻速度比較快的A被前面一隻B擋住了,就可以交換一下,那麼A到B的前面去了,而不用以B的速度前進。要求在一定時間T內,有K只到達barn。問是否可能,如果可能,需要交換的次數最少是多少。
在題目意思理解清楚之後,就會發現,如果chick的位置離barn比較近,而且它能到達barn,那麼後面的即使追上它,也不用交換,他們可以順序的同時到達barn。但如果靠近barn的chick不能到達,比較遠的速度較快,可以到達,那麼就需要交換。可以到達的chick只需要與在它前面不能到達的交換,而不需要與能到達的交換。
這樣演算法就很簡單了,先按距離排序,從離barn比較近的開始,檢查是否能到,如果不能到,需要交換,swapcnt+1,如果能到,那麼passcnt+1,且totalswapcnt += swapcnt,對於這隻可以到的chick,需要交換的次數是它前面所有不能到的chick數。如果passcnt大於等於要求通過的數,那麼可以結束。
代碼如下:
#!/usr/bin/python#encoding:UTF-8#Filename:AlienLanguage.pyimport sysdef solveN(nkbt,pos,speed): N = nkbt[0] K = nkbt[1] B = nkbt[2] T = nkbt[3] posv = [(pos[i],speed[i]) for i in xrange(N)] posv.sort() passcnt = 0 swapcnt = 0 totalswapcnt = 0 ok = 0 for i in xrange(N-1,-1,-1): if posv[i][1]*T+posv[i][0]>=B: passcnt += 1 totalswapcnt += swapcnt else: swapcnt += 1 if passcnt>=K: ok = 1 break; return (ok,totalswapcnt)inname = "input.txt"outname = "output.txt"if len(sys.argv)>1: inname = sys.argv[1] outname = inname.rstrip(".in") outname = outname + ".out"fin = open(inname,"r")fout = open(outname,"w")testCaseNum = int(fin.readline().rstrip("\n"))for caseNum in xrange(testCaseNum): nkbt = [int(s) for s in fin.readline().rstrip("\n").split()] pos = [int(s) for s in fin.readline().rstrip("\n").split()] speed = [int(s) for s in fin.readline().rstrip("\n").split()] (ok,res) = solveN(nkbt,pos,speed) answer = "Case #%d: " %(caseNum+1) if ok: answer += str(res) + "\n" else: answer += "IMPOSSIBLE" + "\n" fout.write(answer)fin.close()fout.close()
測試通過。