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.