Пройдите в квадрате от клеточки 1 к клеточке 2 так, чтобы посетить все клеточки по одному разу - C (СИ) (76394)

Узнай цену своей работы

Формулировка задачи:

Всем привет. Есть такая задача: Пройдите в квадрате от клеточки 1 к клеточке 2 так, чтобы посетить все клеточки по одному разу, не попадая в черные. Подскажите пожалуйста или дайте ссылку на алгоритм решения этой задачи.

Решение задачи: «Пройдите в квадрате от клеточки 1 к клеточке 2 так, чтобы посетить все клеточки по одному разу»

textual
Листинг программы
#include <iostream>
 
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
 
 
int **m;
int **n;
 
 
int f(int**m, int fi, int fj, int ei, int ej)
{
 int h, tmp, i, j, k, l, n;
 
 h = 0;
 
  if (fi < 0 || fj < 0 || fi > 5 || fj > 5 && h == 0)
   return 0;
 
  if (m[fi][fj] == -1 && h == 0)
   return 0;
 
 
  if (m[ei][ej] == -1 && h == 0)
   return 0;
 
  printf("-------b-f------\n");
  printf("f(): %d %d\n", fi, fj);
  printf("----------------\n");
  for(i=0;i<6;i++)
  {
   for(j=0;j<6;j++)
    printf("%d " , m[i][j]);
   printf("\n");
  }
  printf("-------e-f------\n");
 
 // проверка остались ли еще нули
 k = 0;
 for(i = 0; i < 6; i++)
  for(j = 0; j < 6; j++)
    if (m[i][j] == 0)
     k++;
 
 if (k == 1 && m[ei][ej] == 0)
  {
   h = 1;
   // ПУТЬ НАЙДЕН
   printf("h = 1 : %d %d\n", fi, fj);
   return h;
  }
 
 if (k == 0)
 {
 
   printf("k = 0 :\n", fi, fj);
  if (fi == ei && fj == ej)
  {
   h = 1;
   // ПУТЬ НАЙДЕН
   printf("h = 1 : %d %d\n", fi, fj);
   return h;
  }
  else
   return 0;
 }
 else
 {
  if (fi == ei && fj == ej && h == 0)
  {
    return 0;
  }
 }
 
 //
 if (h == 0)
 for(i = 0; i < 6; i++)
 {
  for(j = 0; j < 6; j++)
  {
    l = 0;
    n = 0;
 
    if (i>=0 && (j+1)>=0 && i<=5 && (j+1)<=5 && (m[i][j+1] == -1))
     l++;
    else if (i>=0 && (j+1)>=0 && i<=5 && (j+1)<=5 && (m[i][j+1] == 0))
     n++;
 
    if (i+1>=0 && j>=0 && i+1<=5 && j<=5 && (m[i+1][j] == -1))
     l++;
    else if (i+1>=0 && j>=0 && i+1<=5 && j<=5 && (m[i+1][j] == 0))
     n++;
 
    if (i-1>=0 && j>=0 && i-1<=5 && j<=5 && (m[i-1][j] == -1))
     l++;
    else if (i-1>=0 && j>=0 && i-1<=5 && j<=5 && (m[i-1][j] == 0))
     n++;
 
    if (i>=0 && j-1>=0 && i<=5 && j-1<=5 && (m[i][j-1] == -1))
     l++;
    else if (i>=0 && j-1>=0 && i<=5 && j-1<=5 && (m[i][j-1] == 0))
     n++;
 
    if ((m[i][j] == 0) && n == 1)
    {
     int uy=0;
     if ( i == ei && j == ej)
      uy = 1;
 
     if ( i == fi && j == fj)
      uy = 1;
 
     if ( i == fi+1 && j == fj)
      uy = 1;
 
     if ( i == fi-1 && j == fj)
      uy = 1;
 
     if ( i == fi && j == fj+1)
      uy = 1;
 
     if ( i == fi && j == fj-1)
      uy = 1;
 
     if (uy==0)
     {
 
     printf("m[%d][%d] == 0 : return\n", i, j);
     return 0;
     }
    }
 
    l = 0;
    n = 0;
  }
 }
 
 
 int gf=0;
 
 if (ei+1 <= 5) { if (m[ei+1][ej] == -1)  gf++; }
 else  gf++;
 
 if (ej+1 <= 5) { if (m[ei][ej+1] == -1)  gf++; }
 else gf++;
 
 
 if (ei-1 >= 0) { if (m[ei-1][ej] == -1)  gf++; }
 else gf++;
 
 if (ej-1 >= 0) { if (m[ei][ej-1] == -1)  gf++; }
 else gf++;
 
 if (gf == 4 && h == 0)
  return 0;
 
 
 
 
  //
  printf("%d %d -> %d %d\n", fi, fj, fi+1, fj);
 
  tmp = m[fi][fj];
  m[fi][fj] = -1;
  if (fi+1>=0 && fj>=0 && fi+1<=5 && fj<=5 && m[fi+1][fj] != -1 && h == 0)
   h = f(m, fi+1, fj, ei, ej);
 
  if (h == 1)
  {
   //печать искомого пути
   printf("h = 1 : %d %d\n", fi, fj);
   return h;
  }
  m[fi][fj] = tmp;
 
  //
  printf("%d %d -> %d %d\n", fi, fj, fi, fj+1);
 
  tmp = m[fi][fj];
  m[fi][fj] = -1;
  if (fi>=0 && fj+1>=0 && fi<=5 && fj+1<=5 && m[fi][fj+1] != -1 && h == 0)
   h = f(m, fi, fj+1, ei, ej);
 
  if (h == 1)
  {
   //печать искомого пути
   printf("h = 1 : %d %d\n", fi, fj);
   return h;
  }
  m[fi][fj] = tmp;
 
  //printf("--3--\n");
  printf("%d %d -> %d %d\n", fi, fj, fi-1, fj);
 
  tmp = m[fi][fj];
  m[fi][fj] = -1;
  if (fi-1>=0 && fj>=0 && fi-1<=5 && fj<=5 && m[fi-1][fj] != -1  && h == 0)
   h = f(m, fi-1, fj, ei, ej);
 
  if (h == 1)
  {
   //печать искомого пути
   printf("h = 1 : %d %d\n", fi, fj);
   return h;
  }
  m[fi][fj] = tmp;
 
  //printf("--4--\n");
  printf("%d %d -> %d %d\n", fi, fj, fi, fj-1);
 
  tmp = m[fi][fj];
  m[fi][fj] = -1;
  if (fi>=0 && fj-1>=0 && fi<=5 && fj-1<=5 && m[fi][fj-1] != -1  && h == 0)
   h = f(m, fi, fj-1, ei, ej);
 
  if (h == 1)
  {
   //печать искомого пути
   printf("h = 1 : %d %d\n", fi, fj);
   return h;
  }
  m[fi][fj] = tmp;
 
  return h;
}
 
int main(void)
{
int fi, fj;
int ei, ej;
 int i;
 m = new int*[6];
 n = new int*[6];
 for(i=0;i<6;i++)
 {
  m[i]= new int[6];
  n[i]= new int[6];
 }
 
m[0][0] = -1; m[0][1] = 1; m[0][2] = 0; m[0][3] = 0; m[0][4] = 0; m[0][5] = 0;
m[1][0] = 0; m[1][1] = 0; m[1][2] = 0; m[1][3] = 0; m[1][4] = 0; m[1][5] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 0; m[2][3] = 0; m[2][4] = 0; m[2][5] = 0;
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 0; m[3][4] = 0; m[3][5] = 0;
m[4][0] = 0; m[4][1] = 0; m[4][2] = 0; m[4][3] = -1; m[4][4] = 0; m[4][5] = 0;
m[5][0] = 0; m[5][1] = 0; m[5][2] = 0; m[5][3] = 0; m[5][4] = 0; m[5][5] = 0;
 
fi = 0;
fj = 1;
ei = 3;
ej = 5;
 
f(m, fi, fj, ei, ej);
 
 
 for(i=0;i<6;i++)
 {
  delete[] n[i];
  delete[] m[i];
 }
 delete[] n;
 delete[] m;
 
}

Объяснение кода листинга программы

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

  1. Сначала определяются начальные координаты (fi, fj) и конечные координаты (ei, ej). В данном случае, начальная точка - это клетка (0,1), а конечная точка - клетка (3,5).
  2. Затем вызывается функция f(m, fi, fj, ei, ej), которая пытается найти путь от начальной точки до конечной точки, перебирая все возможные направления.
  3. Внутри функции f, код проверяет, есть ли путь от текущей клетки до конечной точки. Если путь найден, функция возвращает 1, иначе возвращает 0.
  4. Если путь не найден, то код пытается найти путь, начиная с соседних клеток. Если соседняя клетка является проходной (имеет значение -1), то код переходит к следующей клетке. Если соседняя клетка является конечной точкой, то код также переходит к следующей клетке. Если соседняя клетка является непроходной (имеет значение 0), то код проверяет, есть ли путь от начальной точки до конечной точки через эту клетку. Если путь найден, то код возвращает 1. Если путь не найден, то код возвращает 0.
  5. После того, как функция f вернет значение, код печатает найденный путь и значение h. Если h равно 1, то путь найден.
  6. В конце программы, массивы m и n освобождаются с помощью оператора delete. Ошибки и возможные улучшения:
  7. В коде не обрабатывается случай, когда путь от начальной точки до конечной точки не существует. В этом случае, код будет выполняться бесконечно.
  8. Код можно оптимизировать, добавив флаг, который будет отслеживать, была ли уже посещена определенная клетка. Это позволит избежать повторного посещения одних и тех же клеток.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 3.769 из 5
Похожие ответы