问题图片
我正在处理一个编码挑战,在给定一定数量的山p和山s坐标的情况下,我必须计算日光照射山的多少米。
编码挑战说明:https://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=861
我创建了一个具有x坐标和y坐标的Node类,并将它们放在优先级队列中,其中最左侧的坐标排在最前面
double totalLength = 0;
Node peak = priorityQueue.poll();
Node col = null;
while (!priorityQueue.isEmpty()) {
Node nextCoordinates = priorityQueue.poll();
if (peak.yCo > nextCoordinates.yCo) {
col = nextCoordinates;
} else {
// DO SOME CALCULATIONS
peak = nextCoordinates;
}
}
System.out.println(totalLength);
我正在寻找首先在上图中说明的计算,然后在寻找编码挑战的可能更好的解决方案。谢谢
答案 0 :(得分:0)
实际上,我认为您需要按x
降序排列,即最右边的点在前。过程从右向左指向,跟踪当前的最高峰,并初始化到最右边。如果某个点低于当前峰值,则可以忽略。否则,我们使用相似的三角形计算在新的高峰的坡度上可见的太阳的数量,即可见坡度(我们想要的)与总坡度之比等于可见高度的比率(新峰高减去当前峰高) )到总高度。
这是一些伪代码:
Sort array of points, P, by x descending
sun = 0
high = 0
for i = 1 to P.length-1
if P[i].y > P[high].y
a = P[i].y - P[i-1].y
b = P[i].x - P[i-1].x
hdiff = P[i].y - P[high].y
sun = sun + hdiff*sqrt(a*a+b*b)/a
high = i
end
end
翻译成Java:
static double calculateSun(int[] peaks)
{
Point[] pts = new Point[peaks.length/2];
for(int j=0, i=0; i<peaks.length; j++)
pts[j] = new Point(peaks[i++], peaks[i++]);
// Sort by X descending
Arrays.sort(pts, (p1, p2) -> {return p2.x - p1.x;});
double sun = 0;
for(int h=0, i=1; i<pts.length; i++)
{
if(pts[i].y > pts[h].y)
{
int a = pts[i].y - pts[i-1].y;
int b = pts[i].x - pts[i-1].x;
int hdiff = pts[i].y - pts[h].y;
sun += hdiff*Math.sqrt(a*a + b*b)/a;
h = i;
}
}
return sun;
}
测试:
public static void main(String[] args)
{
int[][] tests = {
{ 1100, 1200, 0, 500, 1400, 100, 600, 600, 2800, 0,
400, 1100, 1700, 600, 1500, 800, 2100, 300,
1800, 700, 2400, 500, },
{
0, 1000, 1000, 0,
}};
for (int[] test : tests)
System.out.printf("%.2f\n", calculateSun(test));
}
输出:
1446.34
1414.21
与预期输出匹配的