Proble.m 8 Hetmanów (nierekurencyjnie)

0

Witam!

Postanowiłem rozwiązać problem 8 Hetmanów nierekurencyjnie. Wszystko się ładnie układa, jednak algorytm znajduje 46 prawidłowych ustawień równo 2 razy więcej. Czyżbym zapomniał o jakiejś symetrii? Może ktoś coś poradzić?

 #include <iostream>

using namespace std;

bool szach[10][10];

void Drukuj()				//drukowanie szachownicy szach
{
	for (int i=1;i<=8;i++){
		for (int j=1;j<=8;j++)
			(szach[i][j]==false ? cout<<"O":cout<<"X");
	cout<<endl;
	}
	cout<<endl;
}							 

bool Bicie(int w, int k){								//sprawdzamy czy jest bicie
	 
	for (int l=1;l<w;l++)    //jest bicie w pionie
	if (szach[l][k]==true) return true;

	int kolumna=k+1,wiersz=w-1;   //bicie na ukos do góry w prawo
	while ((kolumna<=8) && (wiersz>=1)){ 
		if (szach[wiersz][kolumna]==true) return true;
		kolumna++;wiersz--;
	}
	kolumna=k-1;wiersz=w-1;
	
	while ((kolumna>=1)&&(wiersz>=1)){

		if (szach[wiersz][kolumna]==true) return true;
		kolumna--;wiersz--;
	}
	
	return false;  //nie ma bicia
}


int main(){

	int l1=1,l2=1,l3=1,l4=1,l5=1,l6=1,l7=1,l8=1,lUstawien=0;
	short flagaStop=1;

	for (l1=1;l1<=8;l1++){
		if(flagaStop>1) {flagaStop--;l1--;}   //flagaStop - by wrócić do poprzednije pętli, np w przypadku dojścia do końca 5 wiersza wracamy do 4 wiersza
		else {
			szach[1][l1]=true;
		}

		if(flagaStop>1) flagaStop--;
		else {
			for (l2;;l2++){
			    if (l2>8) {szach[1][l1]=false;l2=1;l1++;flagaStop=7;break;}
				if (!Bicie(2,l2)) {szach[2][l2]=true;break;}
			 }
		}
			if(flagaStop>1) flagaStop--;
			else { 
				  for (l3;;l3++){
				   if (l3>8) {szach[2][l2]=false;l3=1;l2++;flagaStop=7;break;}
				   if (!Bicie(3,l3)) {szach[3][l3]=true;break;}
				}	
			}
				if(flagaStop>1) flagaStop--;
				else { 
					for (l4;;l4++){
					  if (l4>8) {szach[3][l3]=false;l4=1;l3++;flagaStop=7;break;}
					  if (!Bicie(4,l4)) {szach[4][l4]=true;break;}	
					}
				}
					if(flagaStop>1) flagaStop--;
						else {
							for (l5;;l5++){
							   if (l5>8) {szach[4][l4]=false;l5=1;l4++;flagaStop=7;break;}
							   if (!Bicie(5,l5)) {szach[5][l5]=true;break;}
							}
						}

						if(flagaStop>1) flagaStop--;
						else {
							for (l6;;l6++){
							  if (l6>8) {szach[5][l5]=false;l6=1;l5++;flagaStop=7;break;}
							  if (!Bicie(6,l6)) {szach[6][l6]=true;break;}
							}
						}
							if(flagaStop>1) flagaStop--;
							else {
								for (l7;;l7++){
								  if (l7>8) {szach[6][l6]=false;l7=1;l6++;flagaStop=7;break;}
								  if (!Bicie(7,l7)) {szach[7][l7]=true;break;}
								}
							}
								if(flagaStop>1) flagaStop--;
								else {
							          for (l8;;l8++){
									 // Drukuj();system("pause");
										  if (l8>8) {szach[7][l7]=false;l8=1;l7++;flagaStop=7;break;}
									  if (!Bicie(8,l8)) {szach[8][l8]=true;Drukuj();system("pause");lUstawien++;szach[8][l8]=false;continue;}
									}
								}
								
	}
	
	printf("\nIlosc ustawień wynosi:%d",lUstawien);
	system("pause");
}

Shaom, czytałem, że to zadanie trzeba zrobić rekurencją, ale jeszcze jej niezbyt kumam, dlatego zrobiłem tak. Teraz zabieram się za rozwiązanie rekurencyjne.

Co masz na myśli, że "rozwinąłem" rekurencję? Czy chcąc rozwiązać rekurencyjnie, mam po prostu "zwinąć" ten algorytm? I czy wiesz dlaczego znajduje tylko połowę odpowiedzi?

Ps. Myślę, że nie jest taki strasznie nieczytelny, przecież wystarczy zobaczyć, co robi jedna z pętli for, żeby zrozumieć pozostałe osiem.

0

To że "rozwinąłeś" znaczy tyle ze skopiowałeś 8 razy tą samą pętlę i ifa i jest sobie "zagłębiłeś". Normalnie to byłaby osobna funkcja którą wywołałbyś rekurencyjnie. Moja rada? Napisz ten program tak zeby działał dla N hetmanów a nie tylko dla 8. Napisz to tak żebyś mógł podać przy starcie programu wymiar szachownicy.

0

Dzięki. Z rekurencją sprawa jest bardzo prosta i o wiele bardziej czytelna (no i działa dla szachownicy NxN ).

void SzukajWolnego (short w){
	if (w==N+1) {Drukuj();lUstawien++;return;}//jeśli  mamy całą plansze, drukujemy ją

	for (int l=1;l<=N;l++){
		if (!Bicie(w,l)) {
			szach[w][l]=1;//Drukuj();
			SzukajWolnego(w+1);
			szach[w][l]=0;//Drukuj();
		}
	}
	return;//nie ma wolnego mniejsca
	}

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