google code jam exercise——Picking Up Chicks
这道题是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.py import sys def 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()
测试通过。