给定n个不同整数的集合S,打印S的最大子集S的大小,其中S'中的任意2个数字的总和。不能被k整除。 n =数组中的项数,k =要除以的数。 S =数组
eg: Input from STDIN
10 5
770528134 663501748 384261537 800309024 103668401 538539662 385488901 101262949 557792122 46058493
eg: Input from STDIN
4 3
1 7 2 4
Explanation :
1+7 = 8 : 8 is not evenly divisible
1+4 = 5 : 5 is not evenly divisible
7+4 = 11: 11 is not evenly divisible
1+2 = 3
2+4 =6
2+7 = 9
Those are divisible by 3, so the subset S' = {1,7,4) of size 3.
代码:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int k = in.nextInt();
long arr[] = new long[n];
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
}
final Set<Long> subset = new LinkedHashSet<>();
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
long sum = arr[i] + arr[j];
if (sum % k != 0) {
subset.add(arr[i]);
subset.add(arr[j]);
}
}
}
System.out.println(subset.size());
}
我得到第二个输入的正确答案即。 3.但是,第一次输入我得到9,我期待吐出6。
答案 0 :(得分:1)
我不能轻易按照你的算法中的想法。是什么让你认为它应该有效?
相反,这是另一个想法。规则是,如果i
,基本集中的两个元素j
和(i + j) % k == 0
都不能同时进入子集。假设i和j都是正数,则与(i % k == 0 && j % k == 0) || i % k + j % k == k
相同。所以我想用剩余模数k对元素进行分组。对于具有余数r
和k - r
(1&lt; = r&lt; k)的任何两个这样的组,我可以安全地将一个组添加到子集中,并且我将想要添加两个中的较大者。我还可以从组中添加一个元素,余数为0(不是两个,因为它们的和可以被k整除)。如果k是偶数,我也可以只从组中添加一个余数为k / 2的元素。
编辑:代码可能更精确,所以这里是:
// assume all elements > 0
static Set<Integer> findLargestSubset(int k, int... baseSetElements) {
List<Integer> asList = IntStream.of(baseSetElements).boxed().collect(Collectors.toList());
Set<Integer> baseSet = new HashSet<Integer>(asList);
int n = baseSet.size();
// group elements from set by their remainder modulus k
List<List<Integer>> elementsByModulus = new ArrayList<>();
for (int ix = 0; ix < k; ix++) {
elementsByModulus.add(new ArrayList<>());
}
for (int i : baseSet) {
if (i <= 0) {
throw new IllegalArgumentException("" + i);
}
elementsByModulus.get(i % k).add(i);
}
Set<Integer> largestSubset = new HashSet<>(n);
for (int remainder = 1; remainder < (k + 1) / 2; remainder++) {
List<Integer> groupR = elementsByModulus.get(remainder);
List<Integer> groupKMinusR = elementsByModulus.get(k - remainder);
// add larger group to result
if (groupR.size() > groupKMinusR.size()) {
largestSubset.addAll(groupR);
} else {
largestSubset.addAll(groupKMinusR);
}
}
// add one element with remainder 0 if any
if (!elementsByModulus.get(0).isEmpty()) {
largestSubset.add(elementsByModulus.get(0).get(0));
}
// if k is even, add one element with remainder k / 2 if any
if (k % 2 == 0 && !elementsByModulus.get(k / 2).isEmpty()) {
largestSubset.add(elementsByModulus.get(k / 2).get(0));
}
return largestSubset;
}
对于您问题中的第一个示例,这会给出[800309024, 557792122, 384261537, 538539662, 770528134, 101262949]
,因此大小为6。