Задача.Найдите закономерность и напишите программу, которая выводит аналогичную таблицу для любых чисел [latex]n>0[/latex] (количество столбцов) и [latex]m>0[/latex] (количество строк).
Совет. Если закономерность разгадать не получается, попробуйте воспользоваться Онлайн-энциклопедией целочисленных последовательностей.
1+12+33+64+105+156+217+288
12+33+64+105+156+217+288+1
33+64+105+156+217+288+1+12
64+105+156+217+288+1+12+33
105+156+217+288+1+12+33+64
156+217+288+1+12+33+64+105
217+288+1+12+33+64+105+156
Тесты
№ | [latex]m[/latex] | [latex]n[/latex] | Результат |
1 | 5 | 13 | 1+12+33+64+10 12+33+64+105+ 33+64+105+1+1 64+105+1+12+3 105+1+12+33+6 |
2 | 8 | 11 | 1+12+33+64+ 12+33+64+1+ 33+64+1+12+ 64+1+12+33+ 1+12+33+64+ 12+33+64+1+ 33+64+1+12+ 64+1+12+33+ |
3 | 11 | 20 | 1+12+33+64+105+156+2 12+33+64+105+156+217 33+64+105+156+217+1+ 64+105+156+217+1+12+ 105+156+217+1+12+33+ 156+217+1+12+33+64+1 217+1+12+33+64+105+1 1+12+33+64+105+156+2 12+33+64+105+156+217 33+64+105+156+217+1+ 64+105+156+217+1+12+ |
Код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
#include <iostream> #include <stdio.h> #include<cmath> using namespace std; int m, n, max_q; // длина и ширина таблицы, максимальное количество чисел в строке int element(int i) // формула для i-того элемента последовательности { i++; return i*i+4*(i*i-i); } int length_of_element(int el) // длина i-того элемента { if( el==0|| el==1 ) return 1; return ceil(log10(el)); } int max_quantity() // максимальное количество чисел в строке { int max_q=0; int length=0; for(int j=0; true; j++) { int elem = element(j); int length_el = length_of_element(elem); if(length + length_el <= n) // проверяем, "поместится" ли в строку очередное число { length += length_el; max_q++; if(length == n) return max_q; } else // если число не "влезает", добавляем "+" { max_q++; return max_q; } if(length+1 <= n) // если число "поместилось", но осталось место еще для одного символа, тоже добавляем "+" { length += 1; if(length == n) return max_q; } } return max_q; // такая ситуация невозможна } int line(int i) // печать i-той строки { int length=0; for(int jj=i; true; jj++) { int j = jj % max_q; // формула циклического сдвига чисел в строке int elem = element(j); // число которое мы будем выводить int length_el = length_of_element(elem); // длина числа if(length + length_el <= n) // если полученная нами длина все еще меньше заданного количества столбцов, мы выводим число { length += length_el; cout << elem; if(length == n) { cout << endl; return length; } } else // если длина получается больше, мы "отрезаем" от числа нужное количество символов { int excess = length+length_el-n; for(int z = 0; z < excess; ++z) elem /= 10; cout << elem << endl; return length; } if(length + 1 <= n) // проверяем, нужно ли выводить "+" { length += 1; cout << "+"; if(length == n) { cout << endl; return length; } } } return 0; } int main() { cin >> m >> n; // параметры таблицы max_q = max_quantity(); // вычисляем максимально возможное количество чисел в строке for(int i=0; i<m; i++) line(i); // вывод таблицы return 0; } |
Алгоритм
В данной задаче закономерностью является последовательность двенадцатиугольных чисел, общая формула которых имеет вид::
[latex]n^2+4\cdot(n^2-n)[/latex]Для удобства выполнения циклических операций я изменила формулу последовательности так, чтобы результат был верным при нумерации с нуля.
В каждой следующей строке мы сдвигаем последовательность на одно число влево.
Чтобы число столбцов [latex]n[/latex] соответствовало числу символов в каждой строке, мы выводим числа по одному, каждый раз проверяя, не превысила ли общая длина строки заданное число [latex]n[/latex]. Если длина все-таки получается больше, мы выводим то количество символов, которое помещается в данную строку, а остальные отбрасываем.
Стилистическое замечание — для лучшего восприятия следует подровнять под if и else фигурные скобки {}, а то они у вас в одних местах поставлены ровно, а в других — нет.
Спасибо за замечание, исправила
Не везде.
Как я понял, вы решили использовать GNU стиль? На мой взгляд он самый сложный, трудоёмкий и вычурный. Но выбор за Вами.
Теперь нужно строго придерживаться выбранного стиля. Фигурные скобки на отдельном уровне отступов. До скобок 2 пробела, после скобок — 1 пробел. При описании функций перед скобками отступ не делается. Тип возвращаемого значения — в отдельной строке.
— Не следует именовать функции заглавными буквами. Нужно выбирать «говорящие» имена .
— Пожалуйста, пишите комментарий к коду по крайней мере при определении каждой функции. Не нужно писать комментарии, которые повторяют код — return i*i+4*(i*i-i); // a_i=i*i+4*(i*i-i).
Я понимаю, что Вы вряд ли сядете сейчас читать 800 страниц Стива Макконнелла «Совершенный код», но обязательно посмотрите здесь 3 первых коротких правила.
— Дайте ссылку на OEIS, где описана Ваша последовательность.
Спасибо, Игорь Евгеньевич. Я исправила.
Спасибо. Зачтено.