牛吃药 HackerRank - charging-the-batteries JAVA

92 篇文章 0 订阅
75 篇文章 0 订阅

D - 牛吃药 [PSA]

 HackerRank - charging-the-batteries 

问题描述

半个月之前Alice买了一些竹竿,拼接之后Alice把它截成等长的四段,围出一个正方形的牛棚用来养牛。由于Alice的畜牧经验不足,这头牛患了病。Alice找到当地的兽医开药,并药物拌入饲料喂给这头牛。

假设这个牛棚是个边长为N的正方形,牛棚中所有的点描述为从(0,0)到(N,N)的坐标,牛棚的边缘的各点都堆有饲料,而其中只有M个点放置的是拌有药品的饲料。

假设牛在吃完一堆饲料再吃下一堆时,只会选择与刚吃完这堆相邻近的饲料。现在这头牛需要吃K堆含药饲料才能痊愈,吃每堆饲料要花1分钟。 
若从吃完第一堆开始计时,请问这头牛最少要额外花几分钟才能达到吃药的目标

数据输入

第一行有三个整数N,M,K

接下来有M行,每行两个整数表示拌入药物的饲料的坐标,题目保证给出的坐标在正方形的边缘

  • 1 ≤ N,M ≤105
  • 1 ≤K ≤ M
  • 0 ≤ xi,yi≤N
  • xi与yi至少有一个为0或为N(保证坐标在正方形牛棚的边缘)

数据输出

输出一行,一个整数,代表牛吃到相应数量的药最短可能花费的时间

样例1

输入样例

5 5 3
5 3
0 0
0 4
3 0
1 5

输出样例

6

提示

输入样例的解如下图示,牛从E开始吃第一堆。吃完E点的第一堆开始计时,第1分钟在点(0,5)吃,第2分钟在点(0,4)吃,…直到第6分钟吃完(0,0)的饲料,吃了3次药达到目标,花费6分钟。当然,如果牛先从B开始然后顺时针吃C和E也可以,同样花费6分钟

这里我是逆时针的,将各坐标按四条边的顺序展开,就像拆盒子,将二维转换成一维。 顺时针同理。

总的点的个数为4*(n+1)-4   注意是能取到N,N的 所以应该是N+1

本来考虑对每个点都要枚举 但研究后发现只需要将有药的点加入LIST然后按大小(一维化后有大小)排序,直接可以很方便的取到位置i和位置i+k-1(要去掉自身的1)之间的距离,方便快捷!在枚举上加了点贪心的思想。

对于遍历LIST可能i+k-1越界的情况,可以通过取余%s.size()来循环,注意当对一个点循环的时候,初始位置的点相当于转了一周了,因此要加上总的点的个数即4*(n+1)-4。

题目因为可以取到0,0和n,n 所以经常在具体+1或者-1的问题上卡一会,需要有足够的逻辑推理能力分析好,或者做的多了就有经验了!

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(),m = sc.nextInt(),k=sc.nextInt();
//		int arr[] = new int[4*(n+1)-4];
		int x=0,y=0,p=0;
		ArrayList<Integer> s = new ArrayList<Integer>();
		while(m-- !=0) {
			x = sc.nextInt();
			y = sc.nextInt();
			if(y==0)
				p=x;
			else if(x==n)
				p=n+y;
			else if(y==n)
				p=2*n+(n-x);
			else if(x==0)
				p=3*n+(n-y);
			
			s.add(p);
		}
		Collections.sort(s);
		int ans=999999;
		int temp,mid;
		for (int i = 0; i < s.size(); i++) {
			if(i+k-1>=s.size())
				mid = s.get((i+k-1)%s.size()) + 4*(n+1)-4;
			else
				mid = s.get((i+k-1)%s.size());
			temp = Math.abs(mid-s.get(i));
			if(ans>temp) {
				ans = temp;
			}
		}
		System.out.println(ans);
	}
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值