[Java] PAT 甲级 1033 To Fill or Not to Fill

  代码在PAT上一遍AC,牛客网上精度不对,付出的代价就是花费了很长的时间思考各种情况以及代码的构思。因为入门比较晚,什么贪心,动态规划就简单知道,所以就是单纯的看数据找思路,很是费劲,不过最后看到全红的时候还是很开心的。
  说一下我的代码思路。假设有M个加油站。用一个M*2的float数组存储数据,之后将数组中的数据进行排序(排序标准为,加油站距起点距离升序排列,如果距离相同则按油价升序排列。)。假设开始满油中途不加油的情况下行使的最大距离为D。
  首先存在一种特殊情况,即不存在距离起点为0的点。之后就是正常能到达目的地计算最便宜的价格。
  在正常情况下,定义一个当前油量C,当前行使距离current_dis,开始点为X,油价为A,距起点距离为B,则在[B,B+D]的这段距离中找到离X最近的并且价格小于等于X的另一个加油站Y,则以到达Y正好油用光的情况计算(C清零)。如果以该条件在[B,B+D]这段距离中找不到N,那么在[B,B+D]这段距离找除了X以外油价最低的点Z,到达Z后更新C和cuurent_dis,再以Z为开始点找下一点,直到current_dis等于目标距离为止。这里面还有几种情况。用代码说明吧。主要代码为43到83行

 	import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
       
    public class Main {

    	static int capacity;
    	static int distance;
    	static int ave_dis;;
    	static int station;
    	static float max;
    	static float[][] data;
    
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		String[] aLine = br.readLine().split(" ");
    		capacity = Integer.parseInt(aLine[0]);
    		distance = Integer.parseInt(aLine[1]);
    		ave_dis = Integer.parseInt(aLine[2]);
    		station = Integer.parseInt(aLine[3]);
    		max = capacity * ave_dis;
    		data = new float[station][2];
    		for (int i = 0; i < station; i++) {
    			String[] bLine = br.readLine().split(" ");
    			data[i][0] = Float.parseFloat(bLine[0]);
    			data[i][1] = Float.parseFloat(bLine[1]);
    		}
    		for (int i = 0; i < station - 1; i++) {
    			for (int j = 0; j < station - 1 - i; j++) {
    				if (data[j][1] > data[j + 1][1]) {
    					change(j, data);
    				} else if (data[j][1] == data[j + 1][1]) {
    					if (data[j][0] > data[j + 1][0])
    						change(j, data);
    				}
    			}
    		}
    		if (data[0][1] != 0) {
    			System.out.println("The maximum travel distance = 0.00");
    			return;
    		}
    
    		float cost = 0;
    		float current_dis = 0;
    		int start = 0;
    		int loc = 0;
    		float current_capacity = 0;
    		while (current_dis != distance) {
    			loc = next(start);
    			if (loc == -1) {
    				if (current_dis + max >= distance) {
    					cost += (distance - (current_dis + current_capacity * ave_dis)) / ave_dis * data[start][0];
    					current_dis = distance;
    					break;
    				} else {
    					if (start == station - 1) {
    						System.out.print("The maximum travel distance = ");
    						System.out.printf("%.2f", data[station - 1][1] + max);
    						return;
    					} else {
    						if (current_dis + max < data[start + 1][1]) {
    							System.out.print("The maximum travel distance = ");
    							System.out.printf("%.2f", current_dis + max);
    							return;
    						}
    						loc = find(start);
    						cost += (50 - current_capacity) * data[start][0];
    						current_capacity = 50 - (data[loc][1] - data[start][1]) / ave_dis;
    						current_dis = data[loc][1];
    					}
    				}
    			} else {
    				float move = data[loc][1] - data[start][1];
    				if (data[loc][1] > distance)
    					move = distance - data[start][1];
    				cost += (move - current_capacity * ave_dis) / ave_dis * data[start][0];
    				current_dis = data[start][1] + move;
    				current_capacity = 0;
    			}
    			start = loc;
    		}
    		System.out.printf("%.2f", cost);
    	}
    
    	static void change(int a, float[][] data) {
    		float per = data[a][0];
    		float subdis = data[a][1];
    		data[a][0] = data[a + 1][0];
    		data[a][1] = data[a + 1][1];
    		data[a + 1][0] = per;
    		data[a + 1][1] = subdis;
    	}
    
    	static int next(int loc) {
    		int result = -1;
    		for (int i = loc + 1; i < station; i++) {
    			if (data[i][0] <= data[loc][0] && data[i][1] - data[loc][1] <= max) {
    				result = i;
    				break;
    			}
    		}
    		return result;
    	}
    
    	static int find(int loc) {
    		int result = loc + 1;
    		for (int i = result + 1; data[i][1] <= max + data[loc][1]; i++) {
    			if (data[result][0] >= data[i][0])
    				result = i;
    		}
    		return result;
    	}
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值