我正在编写一个编程挑战,其中一个问题涉及一个包含/排除原则问题,我认为我已经解决了这个问题,但一些测试用例仍然失败了。我无法想到它们可能是什么(其中2个测试用例失败,但它们没有显示输出)。你能给我一些关于它们可能是什么的想法吗?
原始问题:
K毛毛虫正在通过每片毛虫的N片叶子吃东西 所有毛毛虫都以独特的顺序从一片叶子落到另一片叶子 在0号位置的树枝处,落在两片之间的叶子上 每个履带j都具有相关的跳跃数Aj。一个 毛茸茸的跳跃数j吃叶子的位置 j的倍数。它将以j,2j,3j ......的顺序进行。直到它 到达叶子的末端,它停止并建立它的茧。特定 一组K元素K <-15,N <= 10 ^ 9,我们需要确定数字 未吃的叶子。输入:
N =未吃叶子数量K =毛虫数量A =整数数组 跳数
输出:
整数nu。未吃的叶子
示例输入:
10 3 2 4 5
输出:
4
说明:
[2,4,5]是一个j成员跳跃数,所有叶子是多个 吃掉2,4和5,留下1,3,7,9叶,因此没有。 4
我的解决方案:
static int countUneatenLeaves(int N, int[] A) {
int total = 0;
for (int i = 0; i < A.length; i++) {
int multiplier = (int) Math.pow(-1, i);
total += multiplier * combination(A, i + 1, N);
}
return N - total;
}
public static int combination(int[] elements, int K, int num) {
// get the length of the array
// e.g. for {'A','B','C','D'} => N = 4
int N = elements.length;
// get the combination by index
// e.g. 01 --> AB , 23 --> CD
int combination[] = new int[K];
// position of current index
// if (r = 1) r*
// index ==> 0 | 1 | 2
// element ==> A | B | C
int r = 0;
int index = 0;
int total = 0;
while (r >= 0) {
// possible indexes for 1st position "r=0" are "0,1,2" --> "A,B,C"
// possible indexes for 2nd position "r=1" are "1,2,3" --> "B,C,D"
// for r = 0 ==> index < (4+ (0 - 2)) = 2
if (index <= (N + (r - K))) {
combination[r] = index;
// if we are at the last position print and increase the index
if (r == K - 1) {
//do something with the combination e.g. add to list or print
total += calc(combination, elements, num);
index++;
} else {
// select index for next position
index = combination[r] + 1;
r++;
}
} else {
r--;
if (r > 0) index = combination[r] + 1;
else index = combination[0] + 1;
}
}
return total;
}
private static int calc(int[] combination, int[] elements, int num) {
int eaten = 0;
if (combination.length == 1) {
eaten = (int) Math.floor(num / elements[combination[0]]);
} else {
int lcm = lcm(elements[combination[0]], elements[combination[1]]);
for (int i = 2; i < combination.length; i++) {
lcm = lcm(lcm, elements[combination[i]]);
}
eaten = Math.abs((int) Math.floor(num / lcm));
}
return eaten;
}
private static int lcm(int a, int b) {
return a * (b / findGCD(a, b));
}
private static int findGCD(int number1, int number2) {
//base case
if (number2 == 0) {
return number1;
}
return findGCD(number2, number1 % number2);
}
我自己尝试了很多测试输入但未能找到它打破的情况。我怀疑测试失败涉及大N,好像我采用简单的暴力方法,相同的测试用例会因超时而失败。
有什么想法吗?
答案 0 :(得分:0)
我认为你应该使用long而不是int。因为A的元素可以接近10 ^ 9。所以当num gcd(a,b)很小时,例如1,lcm(a,b)= a * b可能大于0x7FFFFFFF,所以答案是不正确的。