Codeforces #386 C 746 C Tram

C. Tram
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

The tram in Berland goes along a straight line from the point 0 to the point s and back, passing 1 meter per t1 seconds in both directions. It means that the tram is always in the state of uniform rectilinear motion, instantly turning around at points x = 0 and x = s.

Igor is at the point x1. He should reach the point x2. Igor passes 1 meter per t2 seconds.

Your task is to determine the minimum time Igor needs to get from the point x1 to the point x2, if it is known where the tram is and in what direction it goes at the moment Igor comes to the point x1.

Igor can enter the tram unlimited number of times at any moment when his and the tram's positions coincide. It is not obligatory that points in which Igor enter and exit the tram are integers. Assume that any boarding and unboarding happens instantly. Igor can move arbitrary along the line (but not faster than 1 meter per t2 seconds). He can also stand at some point for some time.

Input

The first line contains three integers sx1 and x2 (2 ≤ s ≤ 10000 ≤ x1, x2 ≤ sx1 ≠ x2) — the maximum coordinate of the point to which the tram goes, the point Igor is at, and the point he should come to.

The second line contains two integers t1 and t2 (1 ≤ t1, t2 ≤ 1000) — the time in seconds in which the tram passes 1 meter and the time in seconds in which Igor passes 1 meter.

The third line contains two integers p and d (1 ≤ p ≤ s - 1d is either 1 or ) — the position of the tram in the moment Igor came to the point x1 and the direction of the tram at this moment. If , the tram goes in the direction from the point s to the point 0. Ifd = 1, the tram goes in the direction from the point 0 to the point s.

Output

Print the minimum time in seconds which Igor needs to get from the point x1 to the point x2.

Examples
input
4 2 4
3 4
1 1
output
8
input
5 4 0
1 2
3 1
output
7
Note

In the first example it is profitable for Igor to go by foot and not to wait the tram. Thus, he has to pass 2 meters and it takes 8 seconds in total, because he passes 1 meter per 4 seconds.

In the second example Igor can, for example, go towards the point x2 and get to the point 1 in 6 seconds (because he has to pass 3meters, but he passes 1 meters per 2 seconds). At that moment the tram will be at the point 1, so Igor can enter the tram and pass 1meter in 1 second. Thus, Igor will reach the point x2 in 7 seconds in total.


       题意:有一条直线的电车轨道,长度为s(2<=s<=1000)。电车每走一个单位长度需要时间t1,电车的起点是p(1<=p<=s-1),方向是b。(b只有两个值,如果b的值是1方向是从0到s;如果b的值是-1则方向是s到0。),题中已经说明电车在两端(即0和s位置上转方向的时间可以忽略不计。)同时,我们的主人公 Igor他的初始位置是x1,他去x2。他每走一个单位长度需要时间t2,每个时刻都可以往任意方向走,同时,当他碰到电车时可以坐上电车。 (Igor上车的时间可以忽略不计。)现在请问Igor 最快用多少时间就可以到达x2。


      思路:这个题的做法可以说是各有千秋,我在比赛过程中就想到了不少的方法,(那些方法在结尾说,感兴趣的人可以瞟一眼。)我做这个题的思路倒是比较简单,直接算出两个答案,一个是Igor 不上电车直接到x2的答案,另一个是Igor通过电车到达x2的答案,之后直接取较小的一个就行了。直接去x2的比较好算直接就abs(x2-x1)*t2就行了。而上电车的做法就有点小坑了(我就是一不小心错了一个细节。)要上电车就必须要和电车有一个重合的时候,因为电车的运动轨迹在程序输入数据后就是固定的,所以每次经过x2的时间就不会因为Igor的移动的改变而改变,而且lgor 也没必要刻意提前上车的时间。而且电车唯一在改变方向的时候就只有到达两端的时候,所以Igor就只需站在x1等电车就行了。于是只要模拟一下电车的移动就能算出通过上电车到达x2的时间了。


    于是我就根据这个思路写了一个代码,结果在比赛结束后重测的时候WA了。QwQ(下面是我再比赛结束后修改的AC代码也许不是很简洁。在代码中x1和x2分别用st和en代替。)

#include<iostream>
#include<bits/stdc++.h>

using namespace std;

int main()
{
	int s,st,en;
	while(cin>>s>>st>>en){
		int t1,t2;
		cin>>t1>>t2;
		int p,d;
		cin>>p>>d; 
		int Min=abs(st-en)*t2;//这个就是不上电车直接去x2的时间 
		bool ok;//通过这个ok来记录Igor是否上了电车 
		if(p==st)
			ok=true;
		else
			ok=false;
/*这个就是我刚开始漏了考虑的一个细节,如果刚
开始电车和Igor在同一个位置的话就直接上车了*/
		int time=0;
/*就是用这个time记录通过电车到x2的时间,下面
这个while循环内的内容就是模拟电车运动过程*/
		while(!ok||p!=en){
			if(p==0)  //当电车运动到了两端时改变方向 
				d=1;
			if(p==s)
				d=-1;
			p+=d; 
			if(p==st){
				ok=true;
			}
			time+=t1; //电车每移动了一个单位长度增加时间t1 
		}
		cout<<min(Min,time)<<endl;//最后输出的时候取较小的一个。 
	}
}

       不得不说这个题是算是这个比赛中比较坑的一题,因为它放在了C题同时思路又那么简单,代码实现也不难。于是当时我的那个房间里的人都不敢给代码上锁开始HACK。于是,我的代码就直到最后都没人来HACK,弄得我损失了1000+分。QwQ而且值得一题的是,这个题在比赛结束时候过了初试测试样例的人有1700+人。但是,比赛结束后的重测结束后AC的人就剩600+人了。大坑啊!说到底都是自己考虑的不够全面。


       同时要AC这个题的其他方法就像下面这个代码,其中计算直接去x2的时间还是一样算。但是,对于计算通过电车到达x2的方法就有所不同了,他分别通过六种不同的情况进行了讨论分别返回了不同的值。(通过这种方式的时间复杂度比较低。)下面的就是一个写的思路上比较清楚的代码。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;

int Tram(int s, int x1, int x2, int t, int p, int d) {
	if (x1 < x2 && x1 < p) {   //p在x1和x2之前的情况。 
		if (d == 1) return (2*s-p+x2)*t;  //对于两个电车的初始方向分别讨论 
		else return (p+x2)*t;
	}
	else if (x1 < x2 && x1 >= p) { //x1在p和x2之间的情况(p在左) 
		if (d == 1) return (x2-p)*t;
		else return (p+x2)*t;
	}
	else if (x1 > x2 && x1 > p) {//x1在x2和p的右边的情况 
		if (d == 1) return (2*s-p-x2)*t;
		else return (2*s+p-x2)*t;
	}
	else if (x1 > x2 && x1 <= p) {//x1在x2和p之间的情况(p在右) 
		if (d == 1) return (2*s-p-x2)*t;
		else return (p-x2)*t;
	}
}

int main() {
	int s, x1, x2, t1, t2, p, d;
	scanf("%d%d%d%d%d%d%d", &s, &x1, &x2, &t1, &t2, &p, &d);
	printf("%d\n", min(abs(x1-x2)*t2, Tram(s, x1, x2, t1, p, d)));
	return 0;
}

      我个人还是比较喜欢第二中做法的,因为我们ACMer在AC的同时追求的就是更简洁的代码,更低的时间和空间复杂度。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值