1. 程式人生 > >Google Code-Jam 2008 資格賽B題

Google Code-Jam 2008 資格賽B題

問題:     https://code.google.com/codejam/contest/32013/dashboard#s=p1 解答思路:  由於車輛可以在A,B之間往返,所以時刻表中的車輛可能是返程車輛
 如果返程車輛可以完成時刻表的任務,則儘量使用返程車輛    以題目給出的例子說明: case 1的資料如下  5 //週轉時間  3 2 //A->B 和 B->A 的車次數量  //A->B  09:00 12:00 //必須從A起始,因為不可能是從B來的返程車輛  10:00 13:00 //必須從A起始,因為不可能是從B來的返程車輛  11:00 12:30 //可能是B來的返程車輛
 //B->A  12:02 15:00 //由於週轉時間為5,不可能是從B來的返程車輛,必須從B起始  09:00 10:30 //必須從B起始,因為不可能是從A來的返程車輛  要求:最少需要多少車輛,才能完成該時刻表(儘可能多的使用往返車輛)

程式碼:

# -*- coding: UTF-8 -*-
#第一行為了支援中文

def time2int(time):
	time_list=time.split(":")
	count=int(time_list[0])*60
	count=count+int(time_list[1])	
	return count

# 處理一個case的函式
def solve_one_case( fo ):
	A_train_num=0
	B_train_num=0
	
	#獲取週轉時間T
	T=int(fo.readline())
	
	#獲取 A->B 和 B->A 的車次數
	timetable_count_str=str(fo.readline())
	timetable_count_list=timetable_count_str.split()
	A_timetable_num=int(timetable_count_list[0])
	B_timetable_num=int(timetable_count_list[1])
	
	#讀取A時刻表
	A_timetable_list=[]
	temp_list1=[]
	i=0
	while(i<A_timetable_num):
		temp_str=str(fo.readline())
		temp_list=temp_str.split()
		
		temp_list1=[]
		temp_list1.append(time2int(temp_list[0]))	#出發
		temp_list1.append(time2int(temp_list[1]))	#到達
		temp_list1.append(1)						#始發
		
		A_timetable_list.append(temp_list1)
		i=i+1
		
	#讀取B時刻表
	B_timetable_list=[]
	i=0
	while(i<B_timetable_num):
		temp_str=str(fo.readline())
		temp_list=temp_str.split()
		
		temp_list1=[]
		temp_list1.append(time2int(temp_list[0]))
		temp_list1.append(time2int(temp_list[1]))
		temp_list1.append(1)
		B_timetable_list.append(temp_list1)
		
		i=i+1
	
    #從B中刪除可以從A始發的車輛
	 #A按照到達時間排序,從小到大
	A_timetable_list.sort(key=lambda d:d[1])
	 #B按照出發時間排序,從小到大
	B_timetable_list.sort(key=lambda d:d[0])
	ia=0
	ib=0
	while(ia<A_timetable_num):
		while( ib<B_timetable_num and A_timetable_list[ia][1]+T > B_timetable_list[ib][0]):
			ib=ib+1
		 #出界
		if(ib>=B_timetable_num):
			break
		 #此時ib指向第一個可能點
		B_timetable_list[ib][2]=0
		ia=ia+1
		ib=ib+1
		
	#從A中刪除可以從B始發的車輛
	 #B按照到達時間排序,從小到大
	B_timetable_list.sort(key=lambda d:d[1])
	 #A按照出發時間排序,從小到大
	A_timetable_list.sort(key=lambda d:d[0])
	ia=0
	ib=0
	while(ib<B_timetable_num):
		#不需要考慮的這麼複雜
		#if(B_timetable_list[ib][2]==0):
		#	ib=ib+1
		#	continue
			
		while( ia<A_timetable_num and B_timetable_list[ib][1]+T > A_timetable_list[ia][0]):
			ia=ia+1
		 #出界
		if(ia>=A_timetable_num):
			break
		 #此時ia指向第一個可能點
		A_timetable_list[ib][2]=0
		ia=ia+1
		ib=ib+1

	
	#統計
	ia=0
	while(ia<A_timetable_num):
		A_train_num = A_train_num + A_timetable_list[ia][2]
		ia=ia+1
		
	ib=0
	while(ib<B_timetable_num):
		B_train_num = B_train_num + B_timetable_list[ib][2]
		ib=ib+1
	
	train_num=[]
	train_num.append(A_train_num)
	train_num.append(B_train_num)
	
	return train_num

#主函式
def solve_all_cases():
	fo=open("B-small-practice.in","r")
	case_num=int(fo.readline())
	i=0;
	while(i<case_num):
		train_num=solve_one_case(fo)
		
		print("Case #"+str(i+1)+": "+str(train_num[0])+" "+str(train_num[1]))
		
		i=i+1
	fo.close()
	return 

#開始執行
solve_all_cases()