NOIP 1999 旅行家的预算 解题报告
最开始写的伪代码如下:
寻找当前油量能到达的最便宜的加油站
如果找到了,那就开过去加油。
如果找不到, 那就寻找最近的比本站便宜的站点
找到的话就加油刚好开过去
找不到的话就寻找次优站点,充满油开过去
如果找不到任何站点,那就输出No Solution
但是发现可以优化结构,就又写了一个:
寻找距离当前站最近的比当前站便宜的站点
如果找到了,油量够就直接开过去,油量不够就冲到刚好可以开过去
如果找不到,就到前面找一个充满油量能到得了的最便宜的站点,充满油开过去。
如果加满油找不到任何站点,那就输出No Solution
代码如下:
#include <stdio.h> #include <stdlib.h> struct dot{ double dis, p; }dots[100001]; double have = 0, used = 0; double d1, c, d2, p; int place = 0; int com(const void *a, const void *b) { struct dot i = *(struct dot *)a, j = *(struct dot *)b; return i.dis - j.dis; } void driveto(int id) { place = id; } int main(int argc, char **argv) { int i; int n, id; double small; scanf("%lf%lf%lf%lf%d", &d1, &c, &d2, &p, &n); dots[0].p = p; dots[n + 1].dis = d1; for(i = 1; i <= n; i++){ scanf("%lf%lf", &dots[i].dis, &dots[i].p); } qsort(dots, n + 2, sizeof(struct dot), com); while(dots[place].dis < d1){ id = -1; for(i = place + 1; i <= n + 1; i++){ if(dots[place].dis + c * d2 >= dots[i].dis){ if(dots[i].p <= dots[place].p){ id = i; break; } }else{ break; } } if(i == place + 1 && id == -1){ printf("No Solution\n"); return 0; } if(id != -1){ if(dots[place].dis + have * d2 >= dots[id].dis){ have -= (dots[id].dis - dots[place].dis) / d2; }else{ used += ((dots[id].dis - dots[place].dis) / d2 - have) * dots[place].p; have = 0; } }else{ small = 100000000; id = -1; for(i = place + 1; i <= n + 1; i++){ if(dots[place].dis + c * d2 >= dots[i].dis){ if(small >= dots[i].p){ small = dots[i].p; id = i; } }else{ break; } } used += (c - have) * dots[place].p; have = c; have -= (dots[id].dis - dots[place].dis) / d2; } place = id; } printf("%.2lf\n", used); return 0; }