Софтуерно Инженерство
Loading...
+ Нов въпрос
g.stoyanov avatar g.stoyanov 776 Точки

Ръководство за решаване на задачи с рисуване на конзолата.

Здравейте, реших да направя едно ръководство по решаване на задачи с рисуване на конзолата. Изпита наближава и се надявам ръководството да ви е от полза.

Първо да спомена за един основен принцип (поне при мен е така) при решаването на тези задачки – Откриването на повторяеми последователности от символи и опростяването им - привеждането им във вид който на нас ни е удобен.

Второ, задължително се запознайте със конструктора на string просто си нямате на представа колко помага при този тип задачи: new string(‘*’, 3) = “***” готино нали J

За да ми е по лесно направо ще започна с примери които са от софтуерната академия:

П.С.: Ще пускам обясненията на задачите веднага като успея да ги напиша!

50
Programming Basics
Valleri avatar Valleri 292 Точки

Благодаря за ръководството!
След като прегледах първите две научих трика :)

Eдно от мен малко по-трудно от дървото -Hourglass- http://pastebin.com/NqzV0hgd

and the tree itself:

Christmas Tree:
Tree

                                               
1
p.tseperski avatar p.tseperski 21 Точки
Страхотна инициатива, благодаря и от мен! :)
1
g.stoyanov avatar g.stoyanov 776 Точки

Пуснах метода ми за третия пример - Fir Tree. Пускам него защото напоследък имам доста работа и не успях да напиша читаво обяснение за по сложните задачи, не ми остава време. Със сигурност следващата задачка ще е от по трудните - обещавам. Ако има някакви въпроси спокойно може да питате тук.

0
coaster avatar coaster 415 Точки

Здравейте, колеги!
Искам да споделя с вас опита си от една задача, над която мислих през последния час, и с гордост заявявам, че я измислих. И тъй като това е тема за упътване за тези задачи, ще се опитам да ви представя логиката си относно 4-та задача от следния изпит:

Telerik Academy Exam 1 @ 6 December 2013 Morning

4 задача: Diamond Trolls
PS: За да ви е по-прегледно с
и гледайте семпълите в нотепад++ или word :)

Samples:

input = 5;

...*****...
..*..*..*..
.*...*...*.
***********
.*...*...*.
..*..*..*..
...*.*.*...
....***....
.....***.....
......*......

input = 7;

....*******....
...*...*...*...
..*....*....*..
.*.....*.....*.
***************
.*.....*.....*.
..*....*....*..
...*...*...*...
....*..*..*....
.....*.*.*.....
......***......
.......*.......

Седя и гледам тези задачи и чета упътванията на колегата, пуснал темата. И си викам - дай да разделя фигурата на няколко части в зависимост от това какви петърни се повтарят във всяка една от тях.
Първото, което забелязвам, е че първият ред е странен и не се връзва с останалите, не прилича на тях. Както му казват на английски - някакъв odd. Също така като се загледам, виждам, че редът, който е изцяло от звездички * също е различен, както и последният ред. Решавам, че ще направя първо тях, нали ми се виждат най-лесни. Оставащите две части по средата също ще разделя в два отделни цикъла. И така, какво имаме вече - диамант, разделен на 5 логически части. Или образно казано - нещо такова:
(за обяснението ще работя с input = 7)

 

Започваме да си набелязваме петърните и техните повторения във всяка една от частите.

1)
[ . * . ]
[4,7,4]
Това е първият ред. При инпут 7, точките са 4. Следователно за тях ще ползваме формулата 7/2 + 1 = 3 + 1 = 4. Ако инпут беше 9 => 9/2 + 1 = 4 + 1 = 5 и т.н. Принтираме първи ред чрез:

Console.WriteLine("{0}{1}{0}", new string('.', ((n/2) + 1)), new string('*', n));

2)
[.*.*.*.]
[3,1,3,1,3,1,3]
[2,1,4,1,4,1,2]
[1,1,5,1,5,1,1]
Тук забелязваме, че стойността и местоположението на звездите не се променя - винаги звездата е една. Това, което се променя, са точките, така че ще си улесним работата и ще направим "картата" само за точките, т.е.
[3,3,3,3]
[2,4,4,2]
[1,5,5,1]
Започвам сега да се чудя какъв да ми е цикъла. И почвам стъпка по стъпка - как мога да представя тези числа с помощта на N = 7 и някаква променлива i, която ще е каунтър на цикъла? (ПП: ЗАДЪЛЖИТЕЛНО си пишете на хартия, мисля, че е невъзможно да се реши такава задача без да се разпишат различни алгоритми!!)
Изразявам си числата така:
3 -> 7/2 - 0          3 -> 7/2 + 0
2 -> 7/2 - 1          4 -> 7/2 + 1
1 -> 7/2 - 2          5 -> 7/2 + 2
Какво забелязвам от тези неща? Че стойностите ми се изменят най-много с 2. Тоест цикълът ще се върти от 0 до 2, или
i < 7/2 или i < n/2.

for (int i = 0; i < n/2; i++)
{
     Console.WriteLine("{0}*{1}*{1}*{0}", new string('.', ((n/2) - i)), new string('.', ((n/2) + i)));
}

3)
Това е редът, съставен само от звездички. При инпут = 7, звездичките са 15 = 7*2 + 1 или n*2 + 1. Печатим го по следния начин:

Console.WriteLine("{0}", new string('*', ((n*2) + 1)));

4) Отново ще разгледаме само промяната на стойностите на точките, защото звездичките в този петърн също са по една.
[ . * . * . * . ]
[1,5,5,1]
[2,4,4,2]
[3,3,3,3]
[4,2,2,4]
[5,1,1,5]
[6,0,0,6]
По логика, подобна на тази в стъпка 2) отново си представяме числата от "картата" ни, за да разберем какъв да ни е цикълът.
Виждаме, че броят на "първите точки" постепенно нараства с 1. Това значи, че цикълът ни може да върти от 1 до 6 включително, или i ще е в интервала [1;7). А сега как да представим "вторите точки"?
5 -> 7 - 1 - 1
4 -> 7 - 2 - 1
3 -> 7 - 3 - 1
2 -> 7 - 4 - 1
1 -> 7 - 5 - 1
0 -> 7 - 6 - 1
И така, стигнахме до заключението, че за "вторите точки" можем да ползваме следната формула: 7 - i - 1 или n - i - 1.

for (int i = 1; i < n; i++)
{
     Console.WriteLine("{0}*{1}*{1}*{0}", new string('.', i), new string('.', (n - i - 1)));
}

5)
[ . * . ]
[7,1,7]
Ако сте прочели всичко до тук, мисля, че няма смисъл да обяснявам как печатим последният ред :)))

Console.WriteLine("{0}*{0}", new string('.', n));

_____________

Целият код: <ТУК>

Буквално преди 24 часа започнах да решавам задачи с рисуване и то едва след като прочетох темата на колегата и съм му безкрайно благодарна за вложения труд! Ако имате забележки - казвайте, ще променям, пък нали всички сме тук, за да си помагаме.
Може би наистина най-важният съвет, който мога да дам на всички ви, е да ползвате хартиени листа, без тях тези задачи са невъзможни за решаване.

УСПЕХ!! :)

16
rosenrusev avatar rosenrusev 175 Точки

Благодаря за обяснението и решението. Имаш +1 от мен.

0
ivelin_m avatar ivelin_m 0 Точки

Благодаря за разяснението на задачата.Ето какво измъдрих аз - Цък Даде ми 100/100 в бгкодер, но все пак дайте някой feedback дали е добър начина. smile

0
StanDimitroff avatar StanDimitroff 90 Точки

Здравей!Благодарности за труда .Можеш само в кода в Pastebin да си поправиш логиката за вторите точки на втория цикъл, защото не намаляват.Иначе тук редът е верен :) Само да вметна, че задачата Caspichania Boats  представлява същата фигура, обърната наобратно :)

0
Gerard avatar Gerard 2 Точки

Благодаря на автора, както и на някой от другите участници в темата. Mного ми помогнахте за този тип задачи. Успях да приложа логиката на автора, леко модифицирана, напасвайки я към задачата с килимите. За да мога да изградя така наречената "карта", просто замених празните пространства, които се появяват през ред, със символа "/" и така намалих символите от 3 до 2. След това търся в стринга символите "//" и ги подменям с "/ " за да добавя празното пространство.

Сложил съм линк с решението ми и допълнителни обяснения.

https://pastebin.com/eGbvwEp7

1
25/02/2018 23:43:25