思路:这个题的做法可以说是各有千秋,我在比赛过程中就想到了不少的方法,(那些方法在结尾说,感兴趣的人可以瞟一眼。)我做这个题的思路倒是比较简单,直接算出两个答案,一个是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的同时追求的就是更简洁的代码,更低的时间和空间复杂度。