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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值