问题 O: [USACO B] 我一向不喜欢的测速仪

题目描述

Farmer John的农场边上的高速公路最近出现了引人注目的流量上升,或者至少Farmer John看起来是这样的。

为了证实这件事,他打算用一组传感器测量公路上的车流量,每个传感器被用来测量一小段路面上的车流量的数值。 不幸的是,某一天经过牛棚的时候,Farmer John被绊倒了,装有传感器的盒子掉进了一个巨大的奶缸,之后它们就不能正常工作了。

比起之前可以产生一个精确的车流量读数,现在每个传感器只能输出一个可能结果的范围。例如,一个传感器可能会给出范围[7,13] ,表示在这段路面上的车流量不小于7,并且不大于13。 

高速公路经过农场的这一段长N 英里,车辆仅从一个方向通过公路,从第1英里驶向第N 英里。Farmer John想要安装N 个传感器——每一个监测高速公路上1英里长的路段。

在其中某些路段上,有能够使得车辆进入高速公路的上匝道;在所有这样的路段上,Farmer John会将传感器装在上匝道上,测量流入的(近似)车流量。在某些路段上有能够使得车辆离开高速公路的下匝道;在所有这样的路段上,Farmer John会将传感器装在下匝道上。每一个路段包含至多一个匝道。如果在公路的一个路段上没有上匝道或下匝道,Farmer John就将传感器装在高速公路的主路上。

 给定Farmer John的N 个传感器的读数,请求出在高速公路第1英里之前和第N 英里之后车流量的最为准确的可能范围。这些范围应当与所有N 个传感器的读数相一致。

输入

输入的第一行包含N (1≤N≤100 )。余下N 行每行按从第1 英里至第N 英里的顺序描述一段1英里长的路段。每行包含一个字符串,为"on"(如果这段路上有一个上匝道),"off"(如果这段路上有一个下匝道),或者是"none"(如果这段路上没有匝道),然后是两个范围为0…1000 的整数,表示这段路上的传感器的读数所给出的下界、上界。如果这段路上包含匝道,传感器读数来自于匝道,否则来自于主路。至少一个高速公路路段的描述会是"none"。

输出

输出的第一行包含两个整数,为第1英里之前的车流量的最准确的可能范围。第二行包含两个整数,为第N 英里之后的车流量的最准确的可能范围。输入保证存在符合要求的解。

样例输入 

解释

4

on 1 1

none 10 14

none 11 15

off 2 3

样例输出 
10 13
8 12
提示

在这个例子中,路段2和路段3的读数组合在一起告诉我们通过这两个路段的车流量为范围[11,14] 之间的某个值,因为只有这个范围与两个读数[10,14] 和[11,15] 均一致。在第1英里,恰有1单位的车辆通过上匝道进入,所以在第1英里之前,车流量一定在范围[10,13] 之内。在第4英里,2单位到3单位之间的车辆通过下匝道离开,所以这段路之后可能的车流量范围为[8,12] 。
 

#include<bits/stdc++.h>
using namespace std; 

struct Road{//描述路段信息
	string type;
	int num1;
	int num2;
};

int n;

int before_lower,before_upper;
int after_lower,after_upper;

void after(Road * r)
{//处理得到第N 英里之后的车流量的最准确的可能范围
	int lower=0,upper=0;//下限和上限
	int flag=0;
	for(int i=0;i<n;i++)
	{//正向处理
		if(r[i].type=="on") 
		{//上匝道
			lower+=r[i].num1;upper+=r[i].num2;
		}
		
		if(r[i].type=="off") 
		{//下匝道
			lower-=r[i].num2;upper-=r[i].num1;
			if(lower<0) lower=0;//下限小于0,则将其令为0(车流量不小于0)
		}
		
		if(r[i].type=="none") 
		{//主路
			if(flag==0)
			{//第一次主路
				lower=max(lower,r[i].num1);upper=max(upper,r[i].num2);
				flag=1;
			}
			lower=max(lower,r[i].num1);upper=min(upper,r[i].num2);
		}
		
	}
	
	after_lower=lower;after_upper=upper;//记录保存第N英里之后的车流量上下限
}

void before(Road * r)
{//处理得到第1 英里之前的车流量的最准确的可能范围
	int lower=0,upper=0;
	int flag=0;
	for(int i=n-1;i>=0;i--)
	{//倒着处理on:下匝道,off:上匝道,其余与after一致
		if(r[i].type=="on") 
		{//下匝道
			lower-=r[i].num2;upper-=r[i].num1;
			if(lower<0) lower=0;//下限小于0,则将其令为0(车流量不小于0)
		}
		
		if(r[i].type=="off") 
		{//上匝道
			lower+=r[i].num1;upper+=r[i].num2;
		}
		
		if(r[i].type=="none") 
		{//主路
			if(flag==0)
			{//第一次主路
				lower=max(lower,r[i].num1);upper=max(upper,r[i].num2);
				flag=1;
			}
			lower=max(lower,r[i].num1);upper=min(upper,r[i].num2);
		}
		
	}
	
	before_lower=lower;before_upper=upper;//记录保存第1英里之前的车流量上下限
}

int main()
{
	cin>>n;
	Road r[n];
	for(int i=0;i<n;i++)
	{//结构体保存输入的内容,便于after和before使用
		cin>>r[i].type>>r[i].num1>>r[i].num2;
	}
	after(r);
	before(r);
	cout<<before_lower<<" "<<before_upper<<endl;
	cout<<after_lower<<" "<<after_upper<<endl;
	
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值