Вы можете сделать этот алгоритм для генерации ваших пар: начните с G + 1 и для каждого целого числа до N / 2 создайте список множителей, которые меньше N. Например, если G = 3 и N = 19, вы начнете с:
- 4: 4, 8, 12, 16
- 5: 5, 10, 15
- 6: 6, 12, 18
- 7: 7, 14
- 8: 8, 16
- 9: 9, 18
Вам необходимо составить пары из этого списка, выбрав любую пару (не считая двойников): 4: 8, 4:12, 4:16, 8:12, 8:16, 12:16, 5: 10, 5:15, 10:15, 6:12, 6:18, 12:18, 7:14, 9:18. Вы можете делать это по одной группе множителей за раз, переходя от G + 1 к N / 2. Сложность этого кода составляет O ((N / 2-G) * K), где K - длина списка умножителей, не более N / (G + 1). Вы можете улучшить это, пропустив числа, которые уже появились в списках множителей (например, нам не нужно иметь дело с 8 в нашем примере).
Код для генерации прост:
int n = 1000;
int g = 1;
boolean[] skipMultiplier = new boolean[n+1];
Set<Pair<Integer,Integer>> pairs = new HashSet<Pair<Integer,Integer>>();
for (int i=g+1; i<n/2+1 ;i++) {
List<Integer> multipliers = new ArrayList<Integer>();
for (int j=2; j< n/i+1 ; j++) {
if (skipMultiplier[i]) {
continue;
}
multipliers.add(i*j);
skipMultiplier[i*j] = true;
Pair<Integer,Integer> pair = new Pair<Integer,Integer>(i,i*j);
pairs.add(pair);
}
for (int j=0; j<multipliers.size()-1; j++) {
for (int k=j+1; k<multipliers.size(); k++) {
Pair<Integer,Integer> pair =
new Pair<Integer,Integer> (multipliers.get(j), multipliers.get(k));
pairs.add(pair);
}
}
}