我给出了相同长度的 n 线段(1维)的坐标,我需要找到这些线段的最小数量以完全覆盖更大的线或找出这是不可能的。
较大的行从 0 开始,以 L 结束。线段可以从 [0-D,L-D] 范围开始,并且所有线段都具有相同的长度 2 * D 。
因此,例如对于以下输入:
15 2 4 // L, n, D
-2 7 // beginning coordinates of line segments
21 14 4
10 4 6 3 16 17 -1 2 14 11 12 8 5 1
9 9 3
-2 -1 4 0 5 -3 6 3 1
14 12 5
-3 -2 7 5 3 -4 2 -5 0 8 9 6
有以下输出:
Case #1: impossible
Case #2: 3
Case #3: 2
Case #4: 2
为了解决这个问题,我使用贪心算法并选择线段,以便它们之间的交叉点最小。这是我的java代码:
// read L, n, D
// read line segments to segments[] array
segments[n] = Integer.MAX_VALUE;
Arrays.sort(segments);
int current = -1;
for (int i = n-1; i >= 0; i--)
if (segments[i] <= 0) {
current = i;
break;
}
if (current == -1) {
System.out.println("Case #" + k + ": impossible");
continue;
}
int count = 1;
boolean poss = true;
for (int i = 0; i < L - 2* D;) {
count++;
int next = getNextSegment(current);
if (next == current) {
poss = false;
break;
}
current = next;
i = segments[current];
}
if (!poss)
System.out.println("Case #" + k + ": impossible");
else
System.out.println("Case #" + k + ": " + count);
这是我的帮助方法,它获取下一个线段:
int getNextSegment(int current) {
int i = current;
while (segments[i] <= segments[current] + 2* D)
i++;
return i-1;
}
我的算法正确地生成了上述输出,但是我的代码中仍然存在一些错误,我无法找到测试用例,我的程序失败了。您认为应该修复什么?
答案 0 :(得分:1)
我设法编辑您的解决方案,为所提供链接上列出的所有数据集生成正确的输出。我的编辑如下:
segments
数组从大小n+1
更改为大小n
,最后删除了Integer.MAX_VALUE条目。segments[i] <= 0
更改为segments[i]-D <= 0
。for (int i = 0; i < L - 2 * D;)
更改为for (int i = 0; i < L - D;)
getNextSegment
方法中添加了边界检查。作为参考,我得到的代码如下:
Arrays.sort(segments);
int current = -1;
for (int i = n-1; i >= 0; i--) {
if (segments[i]-D <= 0) {
current = i;
break;
}
}
if (current == -1) {
System.out.println("Case #" + k + ": impossible");
continue;
}
int count = 1;
boolean poss = true;
for (int i = segments[current]; i < L-D;) {
count++;
int next = getNextSegment(current);
if (next == current) {
poss = false;
break;
}
current = next;
i = segments[current];
}
if (!poss)
System.out.println("Case #" + k + ": impossible");
else
System.out.println("Case #" + k + ": " + count);
编辑后的getNextSegment
方法如下所示:
int getNextSegment(int current) {
int i = current;
while(i < segments.length && segments[i] <= segments[current] + 2 * D)
i++;
return i - 1;
}