Pomoc przy zrozumieniu zadania z main.edu.pl

Pomoc przy zrozumieniu zadania z main.edu.pl
M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

Witam, mam problem ze zrozumieniem zadania z kursu: http://main.edu.pl/pl/user.phtml?op=showtask&task=tet&con=ALG
Nie proszę o jego rozwiązanie tylko o jakieś pomocne wskazówki. Np. jaka struktura powinna reprezentować całą platformę, bo gdyby wziąć każdy punt osobno to wychodzi tablica [1000000][20000]. Kurs zrozumiałem, ale jakoś nie potrafię zastosować przedstawionych tam technik. Z góry dziękuję za każdą pomoc.

0

Do pamiętania istotnych parametrów wystarczy tablica tab typu int[1000000]. tab[k], to wysokość na której znajduje się najwyżej położony kwadracik nad k.

M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

OK, dzięki za pomoc, napisałem program, ale nie wszystko liczy dobrze. W połowie testów jest zła odpowiedź. Może ktoś przeanalizować i powiedzieć co zrobiłem źle:

Kopiuj
 
#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

const int LEN = 1000;
int tab[1000000]; // Liczba/wysokość klocków, które nie objęły całego odcinka
int max_odc[LEN]; // Największa wartość na odcinku
int odc[LEN]; // Liczba klocków, które objęły cały odcinek
int d, n, l, x, iMax, h;

// d - szerokość platformy
// n - liczba klocków
// l - szerokość klocka
// x - pozycja klocka
// iMax - największa wartość w danym przedziale [a, b]
// h- wysokość

void find_max(int a, int b) {
	iMax = 0;
	while((a % LEN) != 0 && a <= b) {
		iMax = max(iMax, tab[a] + odc[a/LEN]);
		a++;
	}
	while((b % LEN) != (LEN - 1) && a <= b) {
		iMax = max(iMax, tab[b] + odc[b/LEN]);
		b--;
	}
	while(a <= b) {
		iMax = max(iMax, max_odc[a/LEN]);
		a += LEN;
	}
	iMax++;
}

void insert_block(int a, int b) {
	while((a % LEN) != 0 && a <= b) {
		tab[a] = iMax - odc[a/LEN];
		max_odc[a/LEN] = max(max_odc[a/LEN], tab[a] + odc[a/LEN]);
		a++;
	}
	while((b % LEN) != (LEN - 1) && a <= b) {
		tab[b] = iMax - odc[b/LEN];
		max_odc[b/LEN] = max(max_odc[b/LEN], tab[b] + odc[b/LEN]);
		b--;
	}
	while(a <= b) {
		odc[a/LEN]++;
		max_odc[a/LEN]++;
		a += LEN;
	}
}

int main() {
	scanf("%d%d", &d, &n);
	while(n--) {
		scanf("%d%d", &l, &x);
		find_max(x, x+l-1);
		//cout << "l: " << l << " x: " << x << '\n';
		insert_block(x, x+l-1);
		iMax  > h ? h = iMax  : h;
		//cout << "h: " << h << '\n';
	}
	printf("%d", h);
	//system("pause");
	return 0;
}
0

Twojego algorytmu nie analizowałem dokładnie, wydaje mi się przekombinowany.
Moja wersja:
Spada nowy klocek, lewy koniec to k, prawy to r. Szukam max(tab[i]) dla k<=i<=r. Zwiększam tab[i] o 1 dla k<=i<=r.
Na końcu szukam max(tab[i]) po wszystkich i.

bogdans
Co innego myślałem, co innego napisałem. Szukam M=max(tab[i]) dla k<=i<=r. Zmieniam tab[i] na M+1 dla k<=i<=r.
M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

Początkowo tak zrobiłem, ale wtedy program nie mieści się w czasie. Musiałem zastosować do tego podział na przedziały, tak jak w ostanim zadaniu przykładowym z kursu: http://main.edu.pl/pl/user.phtml?op=lesson&n=30&page=algorytmika i tu właśnie coś jest nie tak.

M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

Odświeżam, proszę o pomoc, bo nie mogę się doszukać błędu w programie, a ciągle źle liczy

MX
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 13 lat
0

Nie znalazłem błędu w Twoim algorytmie. Być może jest, ale mam hipotezę. Problemy może stwarzać to, że tablice max_odc oraz odc nie są wyzerowane na początku działania programu. Gdyby było to prawdą, to dla n > 1000 mogą powstawać losowe wyniki. Dlatego zawsze warto przy takich zadaniach na początku wyzerować używane tablice.

Edit: Mam dziwne wrażenie, że zły wynik może powstać także wtedy, gdy maksymalna wysokość wzrosła przy ostatnim klocku. Proponowałbym, by nie liczyć wartości h przy każdym klocku, a dopiero po zakończeniu gry. Wtedy trzeba podać cały przedział 1..n.
Jeszcze jedno, pod koniec edycji znalezione: w C++ numeracja tablic zaczyna się od 0 (czyli numeracja max_odc kończy się na 999 999 oraz odc na 999), zaś w zadaniu od 1 (da nam to numery odpowiednio 1 000 000 oraz 1 000). Przekroczenie zakresu może też tworzyć losowe wyniki. Na Twoim miejscu zwiększyłbym jeszcze zakresy ww. tablic o kilka wartości (nigdy nie zaszkodzi).


Not Found
The requested URL /wypasiona_sygnaturka.txt was not found in this brain.
-----
Human/1.0.00 (Earth) Server at Poland Port 65535
edytowany 3x, ostatnio: mnbvcX
M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

Wykorzystałem wszystkie Twoje wskazówki (zwiększenie tablic i ich wyzerowanie, sprawdzanie h na końcu poprzez analizę max_odc), ale nic to nie dało. Połowa zadań cięgle źle. Wyniki różnią się dość znacznie np. " wczytano '3485', a oczekiwano '3675' "

MX
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 13 lat
0

Cały czas niepokoi mnie fragment:

Kopiuj
        while(a <= b) {
                odc[a/LEN]++;
                max_odc[a/LEN]++;
                a += LEN;
        }

Mam wrażenie, że np. w takiej sytuacji:

  • blok segmentów [1,1000] ma maksymalną wysokość 666
  • blok segmentów [1001,2000] ma max wysokość 333
  • blok segmentów [2001,3000] ma znowu 666
  • kładziemy klocek o położeniu [1,3000]

Mam dziwne wrażenie, że wtedy wysokość każdego segmentu po prostu zwiększy się o 1, czyli blok [1001,2000] otrzyma wysokość 334, nie zaś żądane 667.


Not Found
The requested URL /wypasiona_sygnaturka.txt was not found in this brain.
-----
Human/1.0.00 (Earth) Server at Poland Port 65535
M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

Masz rację, już poprawiłem, ale nadal coś jest nie tak, choć wyniki są już bardziej zbliżone ('3530' zamiast '3675'). Teraz jestem pewny, że coś jeszcze jest w tym fragmencie źle i chyba chodzi o tablicę odc. Gdy klocek zajmuje jakiś cały odcinek to odc[a/LEN] + tab[a] powinno być równe max_odc. Myślałem, żeby zmienić wartość tab[a] i powiększyć ją o te puste pola, ale nic to nie dało. Wyniki nawet pozostają te same

Kopiuj
 	while(a <= b) {
		odc[a/LEN]++;
		for(int i = a; i < LEN; i++) {
			tab[i] = iMax - odc[a/LEN];
		}
		max_odc[a/LEN] = iMax;
		a += LEN;
	}
edytowany 1x, ostatnio: mark075
MX
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 13 lat
0

Rozwiązanie podane przez Ciebie wyżej raczej nie powinno zmieścić się w czasie przy złośliwych testach.
Myślę obecnie nad taką zmianą:

  • wyrzucić tablicę odc
  • w tablicy tab przechowywać wysokość w danym segmencie (z późniejszym zastrzeżeniem)
  • w tablicy max_odc wciąż przechowywać najwyższą wysokość w danym bloku
  • dodać tablicę bool-ową np. wypelnione o rozmiarze LEN. Jeżeli wartość dla i-tego bloku będzie wynosić true, znaczy to, że wszystkie segmenty mają taką samą wysokość (i wtedy posługujemy się tablicą max_odc do wyrażenia dowolnej wysokości w tym bloku zamiast odc); false oczywiście na odwrót. Na początku przypisać wtedy każdemu elementowi tablicy true, bo wszystkie segmenty mają w każdym bloku taką samą wysokość (równą 0).

Zauważ, że:

  • jeżeli jakiś klocek przykryje cały blok o numerze i, można ustawić wypelnione[i] = true oraz max_odc[i] = iMax. I to jest "synonimem" przykrycia całego bloku jednym odcinkiem.
  • jeżeli klocek zachodzi tylko częściowo na blok i i już wszystkie wysokości nie są sobie równe, to uaktualniasz tablicę odc dla danego bloku (chyba odc[LEN*i]=max_odc[i], potem tak samo dla LEN*i+1, LEN*i+2 itd. - pętla). Potem zrobisz wypelnione[i] = false i wszystko jest już gotowe do położenia naszego klocka w danym fragmencie bloku. Zauważ, że dla każdego klocka będziemy musieli robić te czynności nie więcej niż 2 razy - dla każdego końca.

Uff.. rzadko się tak rozpisuję :D


Not Found
The requested URL /wypasiona_sygnaturka.txt was not found in this brain.
-----
Human/1.0.00 (Earth) Server at Poland Port 65535
edytowany 1x, ostatnio: mnbvcX
M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

Zrobiłem tak jak mówisz choć nie wiem czy dobrze wszystko zrozumiałem. W ostatnim punkcie chyba chodziło Ci o tablicę tab i zamiast max_odc[i] to iMax(wysokość na której jest nowy klocek). Jeszcze bardzie zbliżyłem się wyniku, ale ciągle to nie to (3620' zamiast '3675'). Za to program znacznie przyspieszył. Przedtem przy ostatnim teście ~0,41s, a teraz 0,12s. Oto jak to rozumiem:

Kopiuj
#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

const int LEN = 1000;
int tab[1000001];
int max_odc[LEN+1];
bool wypelnione[LEN+1];
int d, n, l, x, iMax, h;

// d - szerokość platformy
// n - liczba klocków
// l - szerokość klocka
// x - pozycja klocka
// h- wysokość

void find_max(int a, int b) {
	iMax = 0;
	if(wypelnione[a/LEN] == true)
		iMax = max_odc[a/LEN];
	else 
		while((a % LEN) != 0 && a <= b) {
			iMax = max(iMax, tab[a]);
			a++;
		}
	///////////////////////////////
	if(wypelnione[b/LEN] == true)
		iMax = max_odc[a/LEN];
	else 
		while((b % LEN) != (LEN - 1) && a <= b) {
			iMax = max(iMax, tab[b]);
			b--;
		}
	///////////////////////////////
	while(a <= b) {
		iMax = max(iMax, max_odc[a/LEN]);
		a += LEN;
	}
	iMax++;
}

void insert_block(int a, int b) {
	if((a % LEN) != 0) {
		wypelnione[a/LEN] = false;
		max_odc[a/LEN] = max(max_odc[a/LEN], iMax);
		while((a % LEN) != 0 && a <= b) {
			tab[a] = iMax;
			a++;
		}
	}
	if((b % LEN) != (LEN - 1)) {
		wypelnione[b/LEN] = false;
		max_odc[b/LEN] = max(max_odc[b/LEN], iMax);
		while((b % LEN) != (LEN - 1) && a <= b) {
			tab[b] = iMax;
			b--;
		}
	}
	while(a <= b) {
		wypelnione[a/LEN] = true;
		for(int i = a; i < LEN; i++) {
			tab[i] = iMax; }
		max_odc[a/LEN] = iMax;
		a += LEN;
	}
}

int main() {
	scanf("%d%d", &d, &n);
	for(int i = 0; i < LEN + 1; i++) {
		max_odc[i] = 0;
		wypelnione[i] = true;
	}
	for(int i = 0; i < 1000001; i++) {
		tab[i] = 0;
	}
	while(n--) {
		scanf("%d%d", &l, &x);
		find_max(x, x+l-1);
		insert_block(x, x+l-1);
	}
	for(int i = 0; i <= LEN+1; i++) {
		h = max(h, max_odc[i]);
	}
	printf("%d", h);
	return 0;
}
edytowany 1x, ostatnio: mark075
MX
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 13 lat
0

Ha!
LEN+1 == 1001 :D
Oczywiście zamiast <= LEN+1 powinno być < n (bo analizujemy wszystkie segmenty od 0 do n-1). Tylko w tym razie musisz zamienić jeszcze fragment while(n--) na odpowiednią pętlę for, żeby pozostawić wartość n nienaruszoną; przykładowo for(int i = 0; i < n; i++) {. Powinno zadziałać.


Not Found
The requested URL /wypasiona_sygnaturka.txt was not found in this brain.
-----
Human/1.0.00 (Earth) Server at Poland Port 65535
edytowany 2x, ostatnio: mnbvcX
M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

Gdzie powinno być "< n" ? n to jest liczba klocków i nie pasuje to do ostatniej pętli, chyba, że znowu nie rozumiem ;)

edytowany 3x, ostatnio: mark075
0
Kopiuj
#include <iostream>
using namespace std;

int main(){
    unsigned int d,n,l,x, line=1;
    cin>>d>>n; //width platform & number of blocks
    bool b,arr[d+1][d+1];
    for(int i=0; i<=d; i++)
      for(int j=0; j<=d; j++)
           arr[i][j]=false;
    for(int i=0; i<n; i++){
       cout<<line<<endl;
       cin>>l>>x; //width block & vertices of the platform block line
         do{
             for(int j=x; j<=(l+x); j++){
               if(arr[line][j]==false){ 
                  arr[line][j]=true;
                  b=true;
                  arr[line][x]=false;
                  arr[line][l+x]=false;
               }
               else{b=false; line++; break;}}
            int c=0;
            while(b==true && (line-c)>0){
                 c++;
               for(int j=x; j<=(l+x); j++){
                 if(arr[line-c][j]==false){ 
                   arr[line-c][j]=true;
                   b=true;
                   arr[line-c][x]=false;
                   arr[line-c][l+x]=false;
                 }              
                 else{b=false; break;}}
               if(b==true)
                 for(int j=x; j<=(l+x); j++)
                     arr[line-(c-1)][j]=false;
               else{b=true; break;}
            }
             cout<<line;
         }while(b==false);
    }
    cout<<line;
    return 0;
}

Ja rozwiązałem to tak, ale coś spieprzyłem... :]

M0
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 9 lat
0

@mnbvcX nie może być
for(int i = 0; i < n; i++){...} i
for(int i = 0; i < n; i++) {...}
próbowałem i nie działa, a poza tym nie pasuje, bo trzeba sprawdzić wszystkie elementy max_odc.
@:] zmień strukturę danych i algorytm, bo w najgorszym przypadku będziesz mieć tablicę arr[1000001][1000001] co jest niewykonalne.

EDIT: Zauważyłem literówkę w pętli:

Kopiuj
for(int i = a; i < (a + LEN); i++) {
			tab[i] = iMax; 	
		}

Ale nic to nie dało, wyniki są ciągle złe i do tego program w dwóch ostatnich testach nie mieści się w czasie

EDIT2: W końcu udało mi się to rozwiązać :D Dzięki za pomoc ;)
Zamieszczam listing jakby kogoś interesowało:

Kopiuj
#include <cstdio>
#include <algorithm>

using namespace std;

const int LEN = 1000;
int tab[1000000];
int max_odc[LEN];
int podstawa[LEN];
int d, n, l, x, iMax, h;

// d - szerokość platformy
// n - liczba klocków
// l - szerokość klocka
// x - pozycja klocka
// h- wysokość

void find_max(int a, int b) {
	iMax = 0;
	while((a % LEN) != 0 && a <= b) {
		iMax = max(iMax, tab[a]);
		iMax = max(iMax, podstawa[a/LEN]);
		a++;
	}
	while((b % LEN) != (LEN - 1) && a <= b) {
		iMax = max(iMax, tab[b]);
		iMax = max(iMax, podstawa[b/LEN]);
		b--;
	}
	while(a <= b) {
		iMax = max(iMax, max_odc[a/LEN]);
		a += LEN;
	}
	iMax++;
}

void insert_block(int a, int b) {
	max_odc[a/LEN] = max(max_odc[a/LEN], iMax);
	while((a % LEN) != 0 && a <= b) {
		tab[a] = iMax;
		a++;
	}
	max_odc[b/LEN] = max(max_odc[b/LEN], iMax);
	while((b % LEN) != (LEN - 1) && a <= b) {
		tab[b] = iMax;
		b--;
	}
	while(a <= b) {
		max_odc[a/LEN] = max(max_odc[a/LEN], iMax);
		podstawa[a/LEN] = max_odc[a/LEN];
		a += LEN;
	}
}

int main() {
	scanf("%d%d", &d, &n);
	for(int i = 0; i < n; i++) {
		scanf("%d%d", &l, &x);
		find_max(x, x+l-1);
		insert_block(x, x+l-1);
		iMax  > h ? h = iMax  : h;
	}
	printf("%d", h);
	return 0;
}
edytowany 4x, ostatnio: mark075
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)