[c++] Skyscrapers

0

Witam, mam do napisania następujący program:

Podajemy jakaś liczbę n (n <=15) z której tworzona jest "plansza" n x n , dookoła planszy(polnoc, poludnie, zachod, wschod) użytkownik podaje ile z danego miejsca ścian wieżowców widać np:

mamy planszę 3x3

1 2 3
2 0 0 0 1
3 0 0 0 3
1 0 0 0 3
3 2 1
tam gdzie 0, program sam powinien znaleźć rozwiązanie, dla podanych wieżowców. Wyższe wieżowce zasłaniają te niższe, więc np. w pierwszym wierszu, na 3 miejscu będzie stała liczba 3, gdyż od prawej strony widać tylko 1 wieżowiec itd. Nie szukam oczywiście gotowych rozwiązań, ani nie śmiem prosić o rozwiązanie tego problemu ;-), szukam jedynie porad, wskazówek jak zabrać sie za rozwiązanie podanego problemu.

Na razie mój program wygląda tak:

#include <iostream>
using namespace std;

int main()
{
	int n;
	bool strony = false;
	cout<<"Podaj rozmiar planszy " <<endl;
	cin>>n;

	n=n+2;//dodatkowe miejsce na ilosc scian widocznych

	int **plansza = new int * [n];

	for (int i=0; i<n; i++)
	{
		plansza[i] = new int[n];
	}

	


	for( int w = 0; w < n; w++)
	{
		for( int k = 0; k< n; k++ )
		{
			plansza[w][k] = 0;
		}
	}

	int ile_wiez;

	for(int k=1; k<=n-2; k++) //góra 
	{
			cout<<"Ile widac wiez z miejsca(gora/polnoc) [0]" <<"[" <<k <<"] :" <<endl;
			cin>>ile_wiez;
			
			plansza[0][k]= ile_wiez;
	}			

	for(int w=1; w<=n-2; w++) //prawo 
	{
		cout<<"Ile widac wiez z miejsca(prawo/wschod)["<<w <<"]" <<"["<<n-1<<"]"  <<endl;
			cin>>ile_wiez;
			
			plansza[w][n-1]= ile_wiez;
	}	

	for(int k=1; k<=n-2; k++) //dol
	{
		cout<<"Ile widac wiez z miejsca(dol/poludnie)["<<n-1 <<"]" <<"["<<k<<"]"  <<endl;
			cin>>ile_wiez;
			
			plansza[n-1][k]= ile_wiez;
	}			

	for(int w=1; w<=n-2; w++) //lewo
	{
		cout<<"Ile widac wiez z miejsca(lewo/zachod)["<<w <<"]" <<"["<<0<<"]"  <<endl;
			cin>>ile_wiez;
			
			plansza[w][0]= ile_wiez;
	}

	for(int i=1; i<n; i++)//sprawdzamy jakie wiezowce widac po przeciwnej stronie
	{
		if((plansza[0][i] == plansza[n-1][i]) || (plansza[i][0]==plansza[i][n-1]) ){ strony = true; }
	}

	


	if(strony = true) {cout<<"Brak rozwiazan dla podanej planszy!"<<endl; return 0;}

	for( int i=1; i<=n-2; i++) //sprawdzamy gdzie widac tylko 1 wiezowiec 
	{
		if(plansza[0][i]==1) { plansza[1][i]=n-2; }//polnoc/gora
		if(plansza[i][n-1]==1) { plansza[i][n-2]=n-2; }//wschod/prawo
		if(plansza[n-1][i]==1) { plansza[n-2][i]=n-2; }//poludnie//dol
		if(plansza[i][0]==1) { plansza[i][1]=n-2; }//zachod/lewo

	}

	

	for( int w = 0; w < n; w++)
	{
		for( int k = 0; k< n; k++ )
		{
			
			cout<<plansza[w][k];
			cout<<" ";
		} cout<<endl;
	}



} 

Czyli tak naprawdę nic nie mam ;-). Szukałem także gotowych rozwiązań, ale nic podobnego nie znalazłem, aby podpatrzeć pracę innych. Także reasumując, nie chce aby ktoś ten problem za mnie rozwiązał, a raczej podpowiedział co dalej, czego poszukać, na czym się skupić. Będę bardzo wdzięczny za każda pomoc!

0

w treści brakuje jeszcze stwierdzenia, że w każdym wierszu i kolumnie występuje tylko jeden wieżowiec o zadanej wysokości od 1 do n.

Radzę znaleźć te zagadki i zacznij je najpierw samemu rozwiązywać, by odnaleźć panujące zasady:
#gdy, widać n wieżowców to wtedy od danej strony masz wieżowce poukładane rosnąco
#gdy, widać 1 wieżowiec, to widać tylko najwyższy więżowiec.

...

Używaj własnych funkcji. Pakowanie wszystkiego do main kończy się niezrozumiałym kodem

twój przykład nie ma rozwiązania (po przeciwnych stornach są trójki).

0

Jeśli chodzi o te dwie zasady, to już jestem w trakcie ich wprowadzania do programu, czekam własnie na porady co do 3 kroku ;-), a plansza która podałem była tylko po to aby pokazać o co mniej więcej chodzi, więc jestem tam błąd.

0

Ok, nie bede tworzył nowego tematu wiec zapytam w tym, a więc:

Na chwilę obecną program działa tak:

  1. Szuka gdzie widać tylko 1 wieżowiec ( wtedy stawia n)
  2. Szuka gdzie widać n wieżowców i wpisuje w tą kolumnę(wiersz) liczby od 1 do n
  3. Szuka gdzie widać 2 wieżowce, i jeśli moze, wstawia tam liczbe n-1

Resztę wolnych miejsc wypełniam liczbami losowymi(1 do n, nie powtarzającymi się w danej kolumnie i wierszu), gdy plansza zostaje wygenerowana, sprawdzarka sprawdza czy z każdej strony widać odpowiednią liczbę wieżowców, jeśli wszystkie 4 strony są true, to program się kończy, jeśli false, to zaczyna od nowa.

Jak można się domyślić, ten sposób wymaga prawdopodobnie cudu aby znalazł rozwiązanie, więc pytam się was ;-) jakies porady, pomysły jak to szukanie dobrej planszy przyspieszyć?

0

a gdzie punkt 4?
dla wybranego wiersza kolumny sprawdzasz wszystkie permutacje pasujące do posiadanych wartości, które równocześnie spełniają warunek widoczności wież.
Jeśli w jakimś niewypełnionym miejscy wystąpi ci tylko jedna liczba to uzupełniasz kratkę.
Główny problem tutaj to strategia wybierania wiersza/kolumny (by nie tracić czasu na testowanie czegoś co nie przyniesie rezultatu) oraz sprytnego wyszukiwania permutacji.

Można też spróbować metodami miękkimi, Monte Carlo powinno być łatwe w implementacji i nie trzeba sobie bardzo łamać głowy.
Bierzesz najprostsze rozwiązanie:

1  2  3  4  5  6
2  3  4  5  6  1
3  4  5  6  1  2
4  5  6  1  2  3
5  6  1  2  3  4
6  1  2  3  4  5

przeszukując permutacje kolumn oraz wierszy metodą Monte Carlo, szukasz rozwiązania, które "najlepiej" spełnia warunki widoczności.

1 użytkowników online, w tym zalogowanych: 0, gości: 1