Для заданного
натурального числа n вывести в
порядке возрастания все правильные несократимые дроби, знаменатель которых не
превышает n.
Вход. Первая строка содержит количество тестов t (t
≤ 10). Каждая из следующих t
строк содержит одно натуральное число n
(1 < n ≤ 2000).
Выход. Для каждого
теста вывести в порядке возрастания все правильные несократимые дроби. Соседние
дроби должны быть разделены запятой и одним пробелом.
Пример
входа |
Пример
выхода |
3 2 5
3 |
1/2 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5 1/3, 1/2, 2/3 |
рекурсия
- последовательность Фарея
Сгенерируем
последовательность Фарея порядка 2000 (все дроби со знаменателем, не большим
2000, в возрастающем порядке) и занесем ее в массив. Для вывода дробей для каждого
теста будем проходить по сгенерированному массиву и выводить все дроби со
знаменателями, не большими n.
Пример
Реализация алгоритма
i-ой сгенерированной дробью будет nom[i] / denom[i].
#define MAX 1300000
int nom[MAX], denom[MAX];
Генерируем все
дроби со знаменателем, не большим 2000, в возрастающем порядке и заносим их
числители и знаменатели в массивы nom и denom.
void farrey(int
a1, int b1, int
a2, int b2)
{
if (2000 <
b1 + b2) return;
farrey(a1,b1,a1+a2,b1+b2);
nom[ptr] = a1 + a2; denom[ptr++] = b1 + b2;
farrey(a1+a2,b1+b2,a2,b2);
}
Основная часть
программы. Генерируем правильные несократимые дроби в порядке возрастания при
помощи функции farrey.
ptr = 0;
farrey(0,1,1,1);
Читаем количество тестов.
scanf("%d",&tests);
while(tests--)
{
Переменная flag = 1 до тех пор пока не выведется первая дробь в строке для
заданного n. Дробь выводится только
если ее знаменатель не больше n.
scanf("%d",&n);
flag = 1;
for(i = 0; i
< ptr; i++)
{
if
(denom[i] <= n)
if (flag)
{
printf("%d/%d",nom[i],
denom[i]); flag = 0;
}
else
printf(",
%d/%d",nom[i], denom[i]);
}
printf("\n");
}
Реализация при помощи класса
#include <stdio.h>
#define MAX 1300000
int i, j, ptr, n, tests;
class Fraction
{
public:
int nom,
denom;
Fraction() {nom = denom = 0;};
Fraction(int
nom, int denom) : nom(nom), denom(denom) {};
bool operator== (const
Fraction &a)
{
return
(a.nom == nom) && (a.denom == denom);
}
};
Fraction f[MAX];
void farrey(int
a1, int b1, int
a2, int b2)
{
if (2000 <
b1 + b2) return;
farrey(a1,b1,a1+a2,b1+b2);
f[ptr++] = Fraction(a1 + a2, b1 + b2);
farrey(a1+a2,b1+b2,a2,b2);
}
int main(void)
{
ptr = 0; farrey(0,1,1,1);
scanf("%d",&tests);
while(tests--)
{
scanf("%d",&n);
printf("1/%d",n);
for(i = 0;
i < ptr; i++)
{
if (f[i]
== Fraction(1,n)) continue;
if
(f[i].denom <= n)
printf(",
%d/%d",f[i].nom, f[i].denom);
}
printf("\n");
}
return 0;
}