HighWay这一题描述如下:
给定一条高速公路,
在时间点为0时公路上停了N辆车,每辆车起始位置都不同,
首先输入一个整数N,2 <= N <= 1000.
接着输入N行,每一行格式为3个整数:X, Y and L,分别是一辆车的起始位置,离开位置以及速度。 0 <= X < Y <= 1000000, 0 < L <= 10.
因为高速公路只有一条车道,所以规定行驶在后面的车子不能超过行驶在它前面的车。
链接:http://hihocoder.com/contest/hiho65/problem/1
关于这题的解法,如果把它当做追及问题,就会变得非常非常复杂,我试了一下,感觉好像不是特别难,但是在写的时候遇到各种问题,真心不简单。
所以有大神提供了一种可以用动态规划来进行解决的思路:
http://hihocoder.com/discuss/question/2533
class RunningCar { double start; double end; double speed; double leavingTime; ... };
For startPoint in sortedStarts from the rear curCar = runningCars[startPoint]; For pos from curCar.start+1 to curCar.end timeWithNoOvertaking = maxArrivingTime[pos-1] + 1.0/curCar.speed; timeWithOvertaking = maxArrivingTime[pos]; maxArrivingTime[pos] = max( timeWithNoOvertaking, timeWithOvertaking); End for curCar.setLeavingTime(maxArrivingTime[curCar.end]); End for就上面这一小段,弄清楚了就很简单了。
#include <iostream> #include <map> #include <vector> #include <algorithm> using namespace std; bool isDebug = true; class RunningCar { double start; double end; double speed; double leavingTime; public: RunningCar() { start = end = 0; speed = 0; } RunningCar(double start, double end, double speed) { this->start = start; this->end = end; this->speed = speed; } double getStart() { return start; } double getEnd() { return end; } double getSpeed() { return speed; } double getLeavingTime() { return leavingTime; } void setLeavingTime(double leavingTime) { this->leavingTime = leavingTime; } void display() { cout << "I am a car starts from " << start << " ends at " << end << " with the speed of " << speed << endl; } }; class HighWay { int N; int maxEnd; map<int, RunningCar *> runningCars; vector<int> startPoints; vector<int> sortedStarts; double *maxArrivingTime; public: HighWay() { maxEnd = 0; maxArrivingTime = NULL; } ~HighWay() { if (maxArrivingTime != NULL) { delete[] maxArrivingTime; maxArrivingTime = NULL; } runningCars.clear(); startPoints.clear(); sortedStarts.clear(); } void readDataAndInitialize() { cin >> N; for (int i = 0; i < N; i++) { int start, end, speed; cin >> start >> end >> speed; if (maxEnd < end) maxEnd = end; RunningCar *newCar = new RunningCar(start, end, speed); runningCars[start] = newCar; startPoints.push_back(start); } maxArrivingTime = new double[maxEnd+1]; for (int i = 0; i < maxEnd+1; i++) maxArrivingTime[i] = 0; sortedStarts = startPoints; sort(sortedStarts.begin(), sortedStarts.end()); } void calculateMaxLeavingTime() { int carsRunningAhead = sortedStarts.size(); while (carsRunningAhead > 0) { RunningCar *curCar = runningCars[sortedStarts[carsRunningAhead-1]]; calculateLeavingTimeForCar(curCar); carsRunningAhead--; } } private: void calculateLeavingTimeForCar(RunningCar *curCar) { for (int i = curCar->getStart()+1; i <= curCar->getEnd(); i++) { calculateLeavingTimeForCarInPos(curCar, i); } curCar->setLeavingTime(maxArrivingTime[(int)curCar->getEnd()]); if (isDebug) { printf("The car leaved at time %.2lf\n", curCar->getLeavingTime()); } } void calculateLeavingTimeForCarInPos(RunningCar *curCar, int pos) { double timeWithNoOvertaking = maxArrivingTime[pos-1] + 1.0/curCar->getSpeed(); maxArrivingTime[pos] = max(maxArrivingTime[pos], timeWithNoOvertaking); if (isDebug) { printf("The car starts from %.0lf, ends at %.0lf, current pos at %d, time is %.2lf\n", curCar->getStart(), curCar->getEnd(), pos, maxArrivingTime[pos]); } } public: void showMaxArrivingTime() { for (int i = 0; i < maxEnd+1; i++) { cout << "The "<< i << "th max arriving time is " << maxArrivingTime[i] << endl; } } void showLeavingTime() { for (int i = 0; i < startPoints.size(); i++) { RunningCar *curCar = runningCars[startPoints[i]]; //printf("%.2lf\n", maxArrivingTime[(int)curCar->getEnd()]); printf("%.2lf\n", curCar->getLeavingTime()); } } }; int main() { HighWay highWay; highWay.readDataAndInitialize(); highWay.calculateMaxLeavingTime(); //highWay.calculateLeavingTimeForCar(NULL); if (isDebug) highWay.showMaxArrivingTime(); highWay.showLeavingTime(); system("pause"); return 0; }
void calculateLeavingTimeForCarInPos(RunningCar *curCar, int pos) { double timeWithNoOvertaking = maxArrivingTime[pos-1] + 1.0/curCar->getSpeed(); maxArrivingTime[pos] = max(maxArrivingTime[pos], timeWithNoOvertaking); if (isDebug) { printf("The car starts from %.0lf, ends at %.0lf, current pos at %d, time is %.2lf\n", curCar->getStart(), curCar->getEnd(), pos, maxArrivingTime[pos]); } }
1.在代码重构的时候犯了一个错误,
我定义HighWay类,它里边有个成员变量为double *maxArrivingTime,
我在构造函数里边将它初始化为NULL。
接着在void readDataAndInitialize()函数里边我是为它分配空间并进行初始化,
当时写成了double *maxArrivingTime = new double[maxEnd+1];
for (int i = 0; i < maxEnd+1; i++)
maxArrivingTime[i] = 0;
这样就出错了,同名变量的问题,C++编译的时候不会提示错误,但运行的时候却是会出错的!
2.用示例是可以运行成功,但还是得自己也设计几个例子来测试下
比如如下运行示例:
4 1 5 4 3 6 3 4 5 2 5 8 1
我发现出问题了,所以用isDebug进行信息输出,原来是我最后输出结果的时候出了问题
//printf("%.2lf\n", maxArrivingTime[(int)curCar->getEnd()]); printf("%.2lf\n", curCar->getLeavingTime());
int main() { vector<int> startPoints; map<int, RunningCar *> runningCars; int N; cin >> N; int maxEnd = 0; for (int i = 0; i < N; i++) { int start, end, speed; cin >> start >> end >> speed; if (maxEnd < end) maxEnd = end; RunningCar *newCar = new RunningCar(start, end, speed); runningCars[start] = newCar; startPoints.push_back(start); } double *maxArrivingTime = new double[maxEnd+1]; for (int i = 0; i < maxEnd+1; i++) maxArrivingTime[i] = 0; vector<int> sortedStarts(startPoints); sort(sortedStarts.begin(), sortedStarts.end()); int carsRunningAhead = sortedStarts.size(); while (carsRunningAhead > 0) { RunningCar *curCar = runningCars[sortedStarts[carsRunningAhead-1]]; for (int i = curCar->getStart(); i <= curCar->getEnd(); i++) { double curCarArrivingHereTime = 0; if (i >=1 && maxArrivingTime[i-1] != 0) { curCarArrivingHereTime = maxArrivingTime[i-1] + 1.0/curCar->getSpeed(); } else { curCarArrivingHereTime = ((double)i-curCar->getStart())/curCar->getSpeed(); } maxArrivingTime[i] = max(maxArrivingTime[i], curCarArrivingHereTime); } curCar->setLeavingTime(maxArrivingTime[(int)curCar->getEnd()]); carsRunningAhead--; } for (int i = 0; i < startPoints.size(); i++) { RunningCar *curCar = runningCars[startPoints[i]]; //cout << "The "<< i << "th car leaved at " << maxArrivingTime[(int)curCar->getEnd()] << endl; printf("%.2lf\n", maxArrivingTime[(int)curCar->getEnd()]); } cin >> N; return 0; }