Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
8 / 6 / 6
Регистрация: 15.07.2015
Сообщений: 38
1

Алтарь цветного Бога

08.01.2016, 20:57. Показов 1662. Ответов 25
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вот уже год назад Вася записался в секту. И сегодня они решили построить алтари своему цветному (RGB) Господу.
Алтарь строится из кирпичей 3 цветов (R, G, B). Он строится на фундаменте (фундамент не считается алтарем).

Правила постройки:
1. Если цвета двух соседних треугольников (кирпичи имеют треугольную форму) внизу какого-то треугольника разные, то этот треугольник должен быть третьего цвета;

2. Если цвет двух соседних треугольников внизу совпадает, то этот же цвет должен иметь и текущий треугольник.

3. Алтарь - правильный треугольник со стороной n=3k (k<=10) (фундамент соответственно n+1).

4. Верхушка алтаря должна быть зеленого цвета.

Пример алтаря со стороной n=3:

g }
r b } Алтарь
b g r }
r g g b <--- (фундамент)

Тех. Условия: Считываем целое число F [1;10]. Из этой же строки считываем (через пробел) F фундаментов (последовательностей символов из множества {r,g,b}).
Надо вывести F кусочков фундамента, которых не хватает для того, чтоб вершина была зеленой (п.4). Если нельзя получить зеленую вершину ни одним способом вывести -1.

Пример работы:

Ввод: 2 rgg ggrggrggr

Вывод: b g


-----------------------------------------------
Соображения:
Я пытался замутить БД со всеми возможными вариантами фундаментов, которые выдадут нам зеленую вершину. В итоге я узнал, что кол-во правильных фундаментов для алтаря = 3n где n - длинна алтаря (НЕ ФУНДАМЕНТА). То есть для n=310 кол-во правильных фундаментов = 359049.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.01.2016, 20:57
Ответы с готовыми решениями:

Верите ли Вы в Бога?
Не думайте не чего такого! Но мне хотелось очень узнать, верите ли Вы в Бога?

А вы верите в существование Бога?
Программирование - исключительно логическое занятие. Все программисты - должны быть убеждёнными...

почему ты веришь в бога?
ну товарищи верующие, к вам вопрос (атеисты ясен пень могут не отвечать :D): почему вы верите в...

Почему не стоит верить в бога?
ну начнем с того что гнлупо верить в существование какого то существа которого никто не видел и нет...

25
495 / 377 / 136
Регистрация: 27.01.2015
Сообщений: 1,588
08.01.2016, 21:16 2
Цитата Сообщение от GaldeMarine Посмотреть сообщение
Надо вывести F кусочков фундамента, которых не хватает для того, чтоб вершина была зеленой
то есть к пирамиде мы добавляем еще блоки или заменяем блоки из фундамента?
0
8 / 6 / 6
Регистрация: 15.07.2015
Сообщений: 38
08.01.2016, 21:38  [ТС] 3
Нет. Нам дана часть фундамента. Нам нужно к ней прибавить столько элементов, чтоб ее длинна была n+1 и вершина вышла зеленой.
В примере постройки это правый синий кирпичик в фундаменте.
0
2683 / 2255 / 244
Регистрация: 03.07.2012
Сообщений: 8,198
Записей в блоге: 1
09.01.2016, 08:15 4
В приведенных примерах к фундаменту добавлено по одному камню. Это всегда так или в фундамент можно добавлять сколько угодно камней? Почему-то гугл не находит эту задачу в других местах. Откуда она взялась?
0
306 / 101 / 18
Регистрация: 04.07.2014
Сообщений: 571
09.01.2016, 10:01 5
Сумма цветов при переходе от нижнего ряда к верхнему не меняется.
Так что цвет вершины -- цвет суммы "фундамента".
Если цвет фундамента равен искомому -- задача решена.
Если нет, то нужно вычесть из искомого цвета цвет суммы фундамента и добавить его к фундаменту.

Цитата Сообщение от zer0mail Посмотреть сообщение
Это всегда так или в фундамент можно добавлять сколько угодно камней?
Задача всегда разрешима добавлением не более, чем одного камня.

Добавлено через 3 минуты
Цитата Сообщение от zer0mail Посмотреть сообщение
гугл не находит эту задачу в других местах
Очень похожая задачка была в разделе C ЕГЭ по информатике... Может пару лет назад, может год, сейчас уже и не помню...
0
2683 / 2255 / 244
Регистрация: 03.07.2012
Сообщений: 8,198
Записей в блоге: 1
09.01.2016, 15:36 6
Цитата Сообщение от mporro Посмотреть сообщение
Сумма цветов при переходе от нижнего ряда к верхнему не меняется.
g }
r b } Алтарь
b g r }
Как понять r+b=g и r+b=b+g+r?
0
306 / 101 / 18
Регистрация: 04.07.2014
Сообщений: 571
09.01.2016, 15:57 7
Для цветов можно определить простой моноид с операцией сложения согласно следующим правилам:
https://www.cyberforum.ru/cgi-bin/latex.cgi?r + r \rightarrow r
https://www.cyberforum.ru/cgi-bin/latex.cgi?r + b \rightarrow g
https://www.cyberforum.ru/cgi-bin/latex.cgi?r + g \rightarrow b
И т.д.
Операция будет коммутативна и ассоциативна.

Используя эту операцию можно подсчитать сумму всех цветов в строке. Это тоже будет какой-то цвет. Учитывая, что https://www.cyberforum.ru/cgi-bin/latex.cgi?{c}_{k}^{n+1} = {c}_{k}^{n} + {c}_{k+1}^{n}, где https://www.cyberforum.ru/cgi-bin/latex.cgi?{c}_{k}^{n} -- k-ый элемент в n-ой строке, легко показать, что суммарный цвет в каждой строке не меняется. Следовательно цвет вершины алтаря равен суммарному цвету фундамента.
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
09.01.2016, 15:58 8
Цитата Сообщение от mporro Посмотреть сообщение
Сумма цветов при переходе от нижнего ряда к верхнему не меняется.
С чего вдруг?
G
GG
BRB

R
BG
BBR
0
306 / 101 / 18
Регистрация: 04.07.2014
Сообщений: 571
09.01.2016, 16:10 9
avgoor
Да. Не ассоциативна операция. Сейчас модернизируем.
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
09.01.2016, 16:20 10
Цитата Сообщение от mporro Посмотреть сообщение
Да. Не ассоциативна операция. Сейчас модернизируем.
Просто, для случая, когда операндов больше двух возвращается не цвет, а кортеж цветов, а он имеет свойство порядка.

Добавлено через 8 минут
По теме задачи.
Достраиваем пирамиду до высоты n-1 произвольным способом.
Потом идем от вершины вниз. Вершина зеленая. тогда если
левый кирпич высоты n-1 зеленый, тогда правый - тоже зеленый.
Если левый синий, то правый красный.
если красный - синий.

Так спускаемся до основания.
2
306 / 101 / 18
Регистрация: 04.07.2014
Сообщений: 571
09.01.2016, 17:27 11
Дельного ничего не получается придумать. Не переставляются скобки очевидным образом. То есть, я сейчас не вижу, но возможно он, всё же, есть.

Можно по правилу сложения вычислить следующий ряд, за ним следующий и т.д. до вершины.
Далее по тем же правилам сложения можно достроить пирамиду вниз.

Например, если есть пирамида
G
GG
BRB

но мы хотим B на вершине, то нужно достроить правый скат:
B
Gx
GG?
BRB?
x = B - G = R

B
GR
GGx
BRB?
x = R - G = B

B
GR
GGB
BRBx
x = B - B = B


B
GR
GGB
BRBB

Решение по-прежнему существует всегда при добавлении не более одного кирпича в фундамент.

Добавлено через 17 минут
P.S.
Есть подозрение, что нужно сложить два крайних элемента и вычесть средние элементы.
Т.е. для фундамента BGRBBR вершина (((((B+R) - G) - R) - B) - B) = B

B
GR
BRR
GRRR
RBGBG
BGRBBR
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
09.01.2016, 19:33 12
Лучший ответ Сообщение было отмечено gru74ik как решение

Решение

Цитата Сообщение от avgoor Посмотреть сообщение
Достраиваем пирамиду до высоты n-1 произвольным способом.
Потом идем от вершины вниз. Вершина зеленая. тогда если
левый кирпич высоты n-1 зеленый, тогда правый - тоже зеленый.
Если левый синий, то правый красный.
если красный - синий.
Так спускаемся до основания.
Ну, можно экономнее. Достраиваем заданное начало основания до треугольника. Если вершина зеленая, то достраиваем эту строку зелеными символами до нужной длины и вычисляем цвета вниз. Если же не зеленая, то строку на уровень выше заполняем всю зелеными символами и заполняем цвета вниз:
C++
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/*
Вот уже год назад Вася записался в секту. И сегодня они решили построить алтари
своему цветному (RGB) Господу.
Алтарь строится из кирпичей 3 цветов (R, G, B). Он строится на фундаменте
(фундамент не считается алтарем).
 
Правила постройки:
1. Если цвета двух соседних треугольников (кирпичи имеют треугольную форму) внизу
какого-то треугольника разные, то этот треугольник должен быть третьего цвета;
 
2. Если цвет двух соседних треугольников внизу совпадает, то этот же цвет должен иметь
и текущий треугольник.
 
3. Алтарь - правильный треугольник со стороной n = 3^k (k <= 10)
(фундамент соответственно n+1).
 
4. Верхушка алтаря должна быть зеленого цвета.
 
Пример алтаря со стороной n=3:
 
g }
r b } Алтарь
b g r }
r g g b <--- (фундамент)
 
Тех. Условия: Считываем целое число F [1;10]. Из этой же строки считываем (через пробел)
F фундаментов (последовательностей символов из множества {r,g,b}).
Надо вывести F кусочков фундамента, которых не хватает для того, чтоб вершина была
зеленой (п.4). Если нельзя получить зеленую вершину ни одним способом вывести -1.
 
Пример работы:
 
Ввод: 2 rgg ggrggrggr
 
Вывод: b g
*/
///////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <deque>
#include <cmath>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
///////////////////////////////////////////////////////////////////////////////
typedef std::string                     T_str;
typedef std::vector     < T_str     >   T_strings;
///////////////////////////////////////////////////////////////////////////////
char    color_sum
    (
        char    L,
        char    R
    )
{
    if( L == R )
    {
        return  L;
    }
 
    if( L > R )
    {
        std::swap( L, R );
    }
 
    auto    LR  =   T_str{L} + R;
 
    if( LR == "bg" )
    {
        return  'r';
    }
 
    if( LR == "br" )
    {
        return  'g';
    }
 
    if( LR == "gr" )
    {
        return  'b';
    }
 
    return  0;
}
///////////////////////////////////////////////////////////////////////////////
T_str   get_right_side_of_altar_with_bottom( T_str  &   altar_bottom )
{
    T_str   result;
 
    while   (
                altar_bottom.size()     >   1
            )
    {
        result.insert
            (
                result.begin        (),
                altar_bottom.back   ()
            );
 
        T_str   new_altar_bottom;
 
        std::transform
            (
                altar_bottom.begin  ()  +   1,
                altar_bottom.end    (),
                altar_bottom.begin  (),
                std::back_inserter  ( new_altar_bottom ),
                color_sum
            );
 
        std::swap
            (
                new_altar_bottom,
                altar_bottom
            );
    }//while
 
    result.insert
        (
            result.begin        (),
            altar_bottom.back   ()
        );
 
    return   result;
}
///////////////////////////////////////////////////////////////////////////////
void    inc_right_altar_side_and_save_result_back
    (
        T_str   &   side,
        T_str   &   back_colors
    )
{
    T_str   new_side{'g'};
 
    std::transform
        (
            side.front()    ==  'g'
                ?   side.begin  ()  +   1
                :   side.begin  (),
 
            side.end            (),
            std::back_inserter  ( new_side ),
 
            [&]                 ( auto  side_color )
            {
                return  color_sum
                            (
                                side_color,
                                new_side.back()
                            );
            }
        );
 
    std::swap
        (
            new_side,
            side
        );
 
    back_colors.push_back
        (
            side.back()
        );
}
///////////////////////////////////////////////////////////////////////////////
T_str   get_altar_bottom_tail
    (
        T_str   const   &   altar_bottom_head,
        int                 k_max
    )
{
    auto    altar_bottom_head_size  =   altar_bottom_head.size();
 
    if  (
            altar_bottom_head_size  ==  std::pow( 3.0, k_max ) + 1
        )
    {
        return  T_str("-1");
    }
 
    double  k_real  =   log( altar_bottom_head_size - 1 ) / log(3);
 
    int     k       =   k_real  ==  ceil( k_real )
                            ?   ++k_real
                            :   ceil( k_real );
 
    auto    target_altar_size       =   pow( 3.0, k ) + 1;
 
    auto    target_altar_tail_size  =       target_altar_size
                                        -   altar_bottom_head_size;
 
    T_str   altar_bottom        =   altar_bottom_head;
    T_str   right_altar_side    =   get_right_side_of_altar_with_bottom( altar_bottom );
    T_str   altar_bottom_tail;
 
    do
    {
        inc_right_altar_side_and_save_result_back
                (
                    right_altar_side,
                    altar_bottom_tail
                );
    }
    while   (
                    altar_bottom_tail.size()
                <   target_altar_tail_size
            );
 
    return  altar_bottom_tail;
}
///////////////////////////////////////////////////////////////////////////////
T_strings   get_altar_bottom_tails
    (
        T_strings   const   &   altar_bottom_heads,
        int                     k_max
    )
{
    T_strings   altar_bottom_tails;
 
    std::transform
        (
            altar_bottom_heads.begin    (),
            altar_bottom_heads.end      (),
            std::back_inserter          ( altar_bottom_tails ),
 
            std::bind                   (
                                            get_altar_bottom_tail,
                                            std::placeholders::_1,
                                            k_max
                                        )
        );
 
    return  altar_bottom_tails;
}
///////////////////////////////////////////////////////////////////////////////
int     main()
{
    const   int     K_MAX   =   10;
    int     F{};
 
    std::cout   <<  "Input data:"
                <<  std::endl;
 
    T_strings   altar_bottom_heads;
 
    std::cin    >>  F;
 
    std::generate_n
        (
            std::back_inserter( altar_bottom_heads ),
            F,
            [&]
            {
                T_str   altar_bottom_head;
                std::cin    >>  altar_bottom_head;
                return  altar_bottom_head;
            }
        );
 
    auto    altar_bottom_tails  =   get_altar_bottom_tails
                                        (
                                            altar_bottom_heads,
                                            K_MAX
                                        );
 
    std::copy
        (
            altar_bottom_tails.begin        (),
            altar_bottom_tails.end          (),
            std::ostream_iterator<T_str>    ( std::cout, "\n" )
        );
 
    std::cout   <<  std::endl;
    system("pause");
}
1
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
10.01.2016, 01:09 13
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну, можно экономнее.
Экономнее нельзя. Чтобы вершина стала зеленая нам нужно достроить одну сторону определенным образом (добавить один кирпич определенного цвета в основание). Но в задаче нужно добавить больше одного кирпича (достроить до n-1 произвольным способом, все зеленые тоже произвольный способ).
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
10.01.2016, 01:50 14
Цитата Сообщение от avgoor Посмотреть сообщение
Экономнее нельзя.
Ну как же нельзя, когда именно можно! Если подниматься до вершины, то придется вычислять цвета во всем алтаре. В моем способе вычисляем цвета не выше уровня p+1, где p - длина заданной части фундамента.
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
10.01.2016, 01:54 15
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну как же нельзя, когда именно можно! Если подниматься до вершины, то придется вычислять цвета во всем алтаре. В моем способе вычисляем цвета не выше уровня p+1, где p - длина заданной части фундамента.
Еще раз: заполнить все недостающие кирпичи фундамента, кроме одного зеленым цветом - тоже произвольный способ.
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
10.01.2016, 01:57 16
Цитата Сообщение от avgoor Посмотреть сообщение
заполнить все недостающие кирпичи фундамента зелены цветом
А это вы откуда взяли?
Ну, не знаю чего вы спорите. Вычислять часть цветов алтаря экономнее, чем все. Против логики не попрешь!
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
10.01.2016, 02:07 17
Цитата Сообщение от Mr.X Посмотреть сообщение
А это вы откуда взяли?
Прошу прощения, неправильно понял.
0
8 / 6 / 6
Регистрация: 15.07.2015
Сообщений: 38
10.01.2016, 16:01  [ТС] 18
[Error] no match for call to '(inc_right_altar_side_and_save_result_back(T_str&, T_str&)::__lambda0) (char&)'

112 строка [Error] 'side_color' was not declared in this scope

108 строка [Error] parameter declared 'auto'

Задача не работает, но за идею спасибо
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
10.01.2016, 19:28 19
Цитата Сообщение от GaldeMarine Посмотреть сообщение
Задача не работает, но за идею спасибо
За идею пожалуйста, но если вы возьмете компилятор с поддержкой C++11, то и задача заработает.
1
0 / 0 / 0
Регистрация: 19.01.2016
Сообщений: 7
21.01.2016, 14:45 20
mporro,
Цитата Сообщение от mporro Посмотреть сообщение
P.S.
Есть подозрение, что нужно сложить два крайних элемента и вычесть средние элементы.
Т.е. для фундамента BGRBBR вершина (((((B+R) - G) - R) - B) - B) = B
B
GR
BRR
GRRR
RBGBG
BGRBBR
Можете подробнее объяснить что это значит? (((((B+R) - G) - R) - B) - B) = B
0
21.01.2016, 14:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.01.2016, 14:45
Помогаю со студенческими работами здесь

В проект симулятора бога требуются энтузиасты
Доброго всем здравия! Для начала опишу суть игры. Просьба не кидаться сильно тапками! Вспомните...

Непонятно изложенная тема про режим бога
Просто создайте папку на рабочем столе следующего содержания. Код Code...

Некоторые доказательства существования бога. С последующими придирками и разоблачениями
Я уже где-то поднимала эту тему. Сейчас повторяюсь: Слышала я что-то такое про теорию струн. Как...

Работа с файлами. Ради Бога, решите пожалуйста. Задание ниже
Дан текстовый файл f, содержащий программу на языке Паскаль. Проверить эту программу на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru