По данному натуральному числу n выведите все двоичные
последовательности длины n, не содержащие двух единиц подряд, в
лексикографическом порядке.
Вход. Одно натуральное число n (n ≤ 20).
Выход. Вывести каждую
последовательность в отдельной строке. Числа в последовательности следует
разделять одним пробелом.
Пример
входа |
Пример
выхода |
3 |
0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 |
комбинаторика
Анализ алгоритма
Пусть x – целое число. В двоичном
представлении число x содержит две
единицы подряд, если x & (x << 1) не равно нулю.
Переберем в
переменной x все числа от 0 до 2n – 1. Если число x в двоичном представлении не содержит
две единицы подряд, то выводим такое двоичное представление.
Второе решение. Рассмотрим рекурсивное решение. Объявим массив и будем строить в нем
требуемые последовательности. Для
текщей позиции p (0 ≤ p < n) есть два варианта установки значений:
·
m[p] = 0, и далее генерируем последовательность с позиции p + 1;
·
m[p] = 1, m[p + 1] = 0, и далее генерируем последовательность с позиции p + 2;
Для второго варианта при p = n – 1 (последняя позиция) совершаем только присваивание m[p] = 1.
Реализация алгоритма
Читаем значение n.
scanf("%d",&n);
Перебираем числа от 0 до 2n
– 1.
for(x = 0; x < (1 << n); x++)
{
Если число x в
двоичном представлении содержит две единицы подряд, то пропускаем его.
if (x &
(x << 1)) continue;
В одной строке выводим двоичный код числа x слева направо в виде
последовательности 0 и 1.
for(i = n -
1; i >= 0; i--)
printf("%d
",(x >> i) & 1);
printf("\n");
}
Реализация алгоритма – рекурсивное решение
#include <stdio.h>
int n;
int m[22];
void gen(int p)
{
if (p >= n)
{
for (int i = 0; i < n; i++)
printf("%d ", m[i]);
printf("\n");
return;
}
m[p] = 0; gen(p + 1);
m[p] = 1; m[p + 1] = 0; gen(p + 2);
}
int main(void)
{
scanf("%d", &n);
gen(0);
return 0;
}
Реализация алгоритма – рекурсивное решение, string
#include <iostream>
#include <string>
using namespace std;
int n;
string s;
void gen(int p, string s)
{
if (p == n)
{
cout << s << endl;
return;
}
gen(p + 1, s + "0 ");
if (p < n - 1) gen(p + 2, s + "1 0
");
else gen(p + 1, s + "1 ");
}
int main(void)
{
cin >> n;
gen(0, "");
return 0;
}