@Shell154

Как работает данная программа C++?

Не могу разобраться как это работает.
#include<iostream>
#include<stdio.h>
using namespace std;


bool P(int *X, int k, int y, int N) // Поиск позиции для ферзя
{
	int i = 0;
	while ((i<k) && (y != X[i]) && (abs(k - i) != abs(y - X[i]))) { i++; }
	if (i == k)
		return true;
	else if (i != k)
		return false;
	else
		return !true && !false;
}

void Backtracking(int k, int &Count, int N, int *X) // Поиск с возвратом позиций
{
	int i, y;
	for (y = 0; y<N; y++)
		if (P(X, k, y, N))
		{
			X[k] = y;
			if (k == N - 1) {
				for (i = 0; i<N; i++) { cout << char('A' + i) << X[i] + 1 << " "; }
				cout << endl;
				Count++;
			}
			Backtracking(k + 1, Count, N, X);
		}
}
int main()
{
	setlocale(LC_ALL, "Rus");
	int N, Count = 0;
	printf ("Введите количество ферзей \n N= ");
	scanf_s ("%i", &N);
	int *X = new int[N];
	for (int i = 0; i<N; i++)
		X[i] = 0;
	printf("Расстановки %d ферзей: \n", N);
	printf("На доске %d на %d \n", N, N);
	Backtracking(0, Count, N, X);
	printf("Всего расстановок: %d \n", Count);
	delete[]X;
	system("pause");
}
  • Вопрос задан
  • 262 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Mercury13
Программист на «си с крестами» и не только
Это обычная учебная программа и я за такой код бил бы по рукам. Нарекания к ней.
1. Одновременное пользование printf и cout. Впрочем, несмотря на глючность, printf — хорошая штука, я и сам сделал более мощный аналог.
2. Есть немного случаев, когда допустимы такие названия переменных/функций.
• для счётчика цикла (i, j, k для переменной, it, jt, kt для итератора, u, v, w для новой фичи Си++11 — того, на что итератор указывает);
• если мы преобразуем научную статью в код, и переменные так названы в статье.
3. Даже название Count слишком расплывчатое — лучше что-то вроде nFound.
UPD2. 4. Я бы переписал функцию P так, что for [0…горизонталь), при бое return false, цикл удался — return true.
5. В музей говнокода!
if (i == k)
    return true;
  else if (i != k)
    return false;
  else
    return !true && !false;

Верно
return (i==k);

Программа проходится по 1-й горизонтали и ставит ферзя на каждую клетку. Если поместился — рекурсивно делает то же самое для 2-й горизонтали, если нет — значит, не повезло. Как только расчёт дойдёт до N-й горизонтали — мы нашли расположение ферзей, можно выводить.

UPD. Ну, допустим, я бы переписал 2-ю функцию так (не меняя порядок параметров).
void Backtracking(int currX, int &nFound, int boardSize, int queenY[])
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы