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()

测试通过。

 

原文地址:https://www.cnblogs.com/Frandy/p/google_code_jam_pick_up_chicks_python.html