Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

4 фирзя на шахматной доске (рекурсия)

20K
12 февраля 2007 года
Inbox
5 / / 01.01.2007
Привет Всем! Нужно расставить 4 ферзя на шахматной доске 4х4, так чтобы они не угрожали друг другу, и вывести удачную расстановку на экран. Я заткнулся на возврате из рекурсивной функции. Если количество ферзей меньше 4-х, рекурсивня функция возвращает 0. В этом случае нужно вернуться назад и изменить координаты ферзей. Например так:

f1 0 0 0
0 0 0 f3
0 f2 0 0
0 0 0 0
возвращаетмся назад до f2 ставим его ниже
f1 0 0 0
0 0 f3 0
0 0 0 0
0 f2 0 0
возвращаемся до f1 ставим его ниже
0 0 f3 0
f1 0 0 0
0 0 0 f4
0 f2 0 0

Может кто поможет? Заранее спасибо. :)

Код:
#include <iostream.h>
#include <conio.h>
 
const int HEIGHT=4;
const int WIDTH=4;
 
int a[HEIGHT][WIDTH]={0};
int c[HEIGHT][2]={0};
int counter=-1;
//---------------------------------------------------------------------------
int setF(int, int);
int checkPosition(int, int);
//---------------------------------------------------------------------------
void main() {
 
    int i, j;
 
    setF(0,0);
 
    for(i=0; i<HEIGHT; i++) {
        for(j=0; j<WIDTH; j++) {
            if(a[j]==0) cout << "0" << " ";
            else cout << "f" << " ";
        }
        cout << endl;
    }
}
//---------------------------------------------------------------------------
int setF(int x, int y) {
 
    int tmp, n=x, m=y;
 
    if(checkPosition(n,m)) {
        counter++;
        a[n][m]=1; c[counter][0]=n; c[counter][1]=m;
    }
    if(n==HEIGHT-1) {
        if(m!=WIDTH-1) { m++; n=0; }
        else if(counter<HEIGHT-1) return 0;
        else return 1;
    }
    else n++;
 
    tmp=setF(n,m);
 
    return tmp;
}
//---------------------------------------------------------------------------
int checkPosition(int x, int y) {
 
    int i, n=x, m=y;
 
    for(i=0; i<HEIGHT; i++)
        if(a[y]==1) return 0;
    for(i=0; i<WIDTH; i++)
        if(a[x]==1) return 0;
 
    while(1) {
        if(n==HEIGHT-1) break; if(m==WIDTH-1) break;
        n++; m++; if(a[n][m]==1) return 0;
    }
    n=x; m=y;
    while(1) {
        if(n==0) break; if(m==WIDTH-1) break;
        n--; m++; if(a[n][m]==1) return 0;
    }
    n=x; m=y;
    while(1) {
        if(n==HEIGHT-1) break; if(m==0) break;
        n++; m--; if(a[n][m]==1) return 0;
    }
    n=x; m=y;
    while(1) {
        if(n==0) break; if(m==0) break;
        n--; m--; if(a[n][m]==1) return 0;
    }
    return 1;
}
[/COLOR]
320
12 февраля 2007 года
m_Valery
1.0K / / 08.01.2007
Поиск не пробовал ? :) Это задача 8 ферзей.
http://www.codenet.ru/search/search.php?q=8+%F4%E5%F0%E7%E5%E9
10K
16 февраля 2007 года
Omega Red
49 / / 15.10.2006
Объясню я принцип решения этой задачи, сам только недавно понял.
Код:
#include <iostream.h>

bool h[8];
bool l[15];
bool r[15];
int pos[8];

int num=0;

void print_solve()
{
        cout<<"Solve "<<num<<": "<<endl;
        for (int i=0; i<8; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                if (j == pos)
                    cout<<1<<" ";
                else cout<<0<<" ";
            }
            cout<<endl;
        }
}


bool solvenext (int move)
{

        if (move==8)
        {
                num++;
                print_solve();
                return(0);
        }

        int n=0;

        while (n<8)
        {
                if (h[n]==0&&l[7+n-move]==0&&r[n+move]==0)
                {
                        pos[move]=n;
                        h[n]=1;
                        l[7+n-move]=1;
                        r[n+move]=1;

                        if (solvenext(move+1)==1)
                                return(1);

                        else
                        {
                                h[n]=0;
                                l[7+n-move]=0;
                                r[n+move]=0;
                        }
                }
               
                n++;
        }

        if (n==8)
        {
                return(0);
        }

}

void main ()
{

int i;

for (i=0; i<8; i++)
        h=0;

for (i=0; i<15; i++)
{
        l=0;
        r=0;
}

solvenext(0);

cout<<"Solves count: "<<num<<"\n";

}


bool h[8];
Счётчик вертикалей, если на вертикали стоит ферзь, то номер этой вертикали равен 1. Если ставим ферзя на какую-нибудь вертикаль, то устанавливаем 1, если убираем - 0.

bool l[15];
Счётчик левых диагоналей. Они располагаются вот так
# # # # # # # 14
# # # # # # # 13
# # # # # # # 12
# # # # # # # 11
# # # # # # # 10
# # # # # # # 9
# # # # # # # 8
0 1 2 3 4 5 6 7
Смотрят вверх влево. К l[0] относится только одна клетка, l[12] - 3 клетки

bool r[15];
Правые диагонали. Начинаются с самой левой верхней клетки, идут вправо а потом вниз.

int pos[8];
Индекс массива - номер строки минус 1, значение элемента - номер столбца

if (h[n]==0&&l[7+n-move]==0&&r[n+move]==0)
Если на вертикали, левой и правой диагоналях чисто, то ставим ферзя в эту клетку, т.е. изменяем значения h[], l[] и r[] на 1, на этих вертикалях и диагоналях ничего нельзя будет ставить.

if (solvenext(move+1)==1)
return(1);
Рекурсия. После установки ферзя проверяется следующая строка, и т.д.

else
{
h[n]=0;
l[7+n-move]=0;
r[n+move]=0;
}

Если возвращаемое значение следующей перестановки 0, то текущая позиция удаляется и пробуется другая комбинация.

if (move==8)
{
num++;
print_solve();
return(0);
}
Если завершены все перестановки, и вызвана функция для 8, т.е. строки которой не существует, то печатается полученная комбинация (строки от 0 до 7 расставлены). Возвращается значение 0, и в верхних функциях подбирается следующая комбинация.


Более менее рассказал, для 4-х можно также легко сделать эту задачу.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог