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;
}

posted @ 2011-07-30 12:41  zqynux  阅读(2163)  评论(0编辑  收藏  举报