#include <stdio.
h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_ROW 9
#define MAX_COLUMN 9
#define MAX 30
// Data
int data[9][9] = {
{1,0,0,0,1,0,1,1,0},
{1,1,0,1,1,1,0,0,1},
{0,1,0,1,1,0,1,0,1},
{0,1,1,0,0,1,0,1,1},
{0,0,1,0,1,0,1,0,0},
{1,1,1,0,0,0,0,1,1},
{1,0,1,1,1,1,1,0,0},
{1,1,1,0,0,0,1,0,1},
{0,0,0,1,1,1,1,1,0}
};
typedef struct POINT{
int row; // Toa do x cua nut
int column; // Toa do y cua nut
int value; // Gia tri 0 hoac 1 cua nut
bool visited; // Danh dau nut da duoc di
qua
struct POINT* prev; // Con tro den nut lien truoc do
truoc khi den nut nay
} point_t;
point_t matrix[MAX_ROW][MAX_COLUMN]; // Ma tran
// Set up Queue
typedef struct
{
point_t data[MAX];
int front;
int rear;
}Queue;
// Ham 1: Khoi tao hang doi
void initQueue(Queue *q)
{
q->front = 0;
q->rear = -1;
// Ham 2: Kiem tra xem hang doi co rong hay khong.
int isEmpty(Queue *q)
{
return (q->rear < q->front);
}
// Ham 3: Kiem tra xem hang doi da day chua.
int isFull(Queue *q)
{
if(q->rear == MAX - 1)
{
return 1;
} else return 0;
}
// Ham 4: Them phan tu vao cuoi (rear) cua hang doi.
void enQueue(Queue *q, point_t x)
{
if (!isFull(q))
{
if(q->rear == MAX - 1)
{
int i = 0;
for(i = q->front; i <= q->rear; i++)
{
q->data[i - q->front] = q->data[i];
}
q->rear = MAX - q->front;
q->front = 0;
q->rear = q->rear + 1;
q->data[q->rear] = x;
}
}
// Ham 5: Lay phan tu dau (front) ra khoi hang doi.
point_t deQueue(Queue *q)
{
point_t d;
if (!isEmpty(q))
{
d = q->data[q->front];
q->front = q->front +1;
}
if (q->front > q->rear)
{
initQueue(q);
};
return d;
}
// Ham kiem tra toa do nam trong ma tran hay khong
bool checkCoordinate(int x, int y)
{
bool ret = false;
if ((0 <= x && x <= 8) && (0 <= y && y <= 8))
{
ret = true;
}
return ret;
}
// Tim cac diem xung quanh cua diem duoc xet nam tren duong di tu diem nguon O(0,0)
den diem dich co gia tri bang 1
void findSurroundingPoint(int x, int y, point_t surroundingPnt[4], int* count)
{
// Khoi tao so bien dem so luong cac nut co the di duoc quanh 1 vi tri
int tempCnt = 0;
// Kiem tra xem vi tri diem ben phai co den duoc khong
if ((checkCoordinate(x, y+1) == true) && (matrix[x][y+1].value == 1))
{
surroundingPnt[tempCnt] = matrix[x][y+1];
tempCnt++;
}
// Kiem tra xem vi tri diem ben duoi co den duoc khong
if ((checkCoordinate(x+1, y) == true) && (matrix[x+1][y].value == 1))
{
surroundingPnt[tempCnt] = matrix[x+1][y];
tempCnt++;
}
// Kiem tra xem vi tri diem ben trai co den duoc khong
if ((checkCoordinate(x, y-1) == true) && (matrix[x][y-1].value == 1))
{
surroundingPnt[tempCnt] = matrix[x][y-1];
tempCnt++;
}
// Kiem tra xem vi tri diem ben tren co den duoc khong
if ((checkCoordinate(x-1, y) == true) && (matrix[x-1][y].value == 1))
{
surroundingPnt[tempCnt] = matrix[x-1][y];
tempCnt++;
}
*count = tempCnt;
}
// Ham in ra duong di ngan nhat
void printPath(int x,int y)
{
int count = 0 , max_count; // Bat dau dem
point_t *destination = &matrix[x][y]; // Con tro tro
den ma tran
int arrRow[100]; // Nhap ma tran
dong
int arrColumn[100]; // Nhap ma tran
cot
while (destination != NULL) // Bat dau
vong lap
{
arrRow[count] = destination->row; // Ma tran
dong chuyen dong trong vong lap while
arrColumn[count] = destination->column; // Ma tran
cot chuyen dong trong vong lap while
destination = destination->prev; // Con tro
tro den cac diem truoc do vua duoc di qua
count++; // tu diem A
ve den diem O
}
printf("\nDuong di ngan nhat tu O(0,0) den A(%d,%d) co do dai la %d
o: \n", x, y, count);
for (int i=count-1 ; i>=0 ; i--) // Dung vong lap
for de in nguoc lai cac diem, tuc la tu O den A
{
printf("(%d,%d)", arrRow[i], arrColumn[i]); // In ra cac
diem da di qua tu O den A
if(i>0)
printf("->"); // In ra
mui ten giua cac diem da di qua
}
}
// Ham tim duong di ngan nhat
void findShortestPath (int x, int y)
{
Queue queue;
initQueue(&queue); // Khoi tao hang doi
matrix[0][0].visited = true; // Danh dau phan tu
(0,0) da di qua
enQueue(&queue,matrix[0][0]); // Cho phan tu (0,0)
vao hang doi
point_t p; // Xem xet diem p
point_t pp[4]; // Xem xet 4 diem
(tren,duoi,trai,phai) xung quanh diem p
int count; // Bat dau dem
bool found = false;
while((isEmpty(&queue) == false) && found == false)
{
p = deQueue(&queue);
findSurroundingPoint(p.row,p.column,pp,&count);
// Tim kiem cac diem xung quanh
int i = 0;
for( i=0 ; i<count ; i++) //
Vong lap for tim kiem diem moi
{
if(pp[i].visited == false)
// Neu tim duoc diem chua di qua
{
matrix[pp[i].row][pp[i].column].visited = true;
// Ghi nhan diem do da di qua
matrix[pp[i].row][pp[i].column].prev = &matrix[p.row][p.column];
// Con tro chi vao diem moi
if(pp[i].row == x && pp[i].column == y)
// Neu duyet den diem cuoi thi dung
{
found = true;
// Neu tim duoc diem dich A thi dung
break;
// Thoat ra khoi vong lap
}
else
{ // Neu
khong phai vay (chua tim duoc diem dich)
enQueue(&queue,pp[i]);
// Tiep tuc cho diem moi vao hang doi
}
}
}
}
if(found ==
true) // Neu tim duoc
diem dich
{
printPath(x,y);
// In ra toa do cac diem tren duong di
}
else{ // Neu
khong tim duoc diem dich
printf("Khong tim duoc duong di tu o xuat phat O den o dich den A.");
// In ra "Khong tim duoc"
}
}
// Ham in ra ma tran
void printMatrix()
{
printf("CHUONG TRINH TIM DUONG DI NGAN NHAT TU O(0,0) DEN A(dong, cot): \n");
printf("\nMa tran 9x9 bieu dien cho mat phang 2 chieu: \n");
int i, j = 0;
for( i=0 ; i<MAX_ROW ; i++)
{
for( j=0; j<MAX_COLUMN; j++)
{
printf(" %d",data[i][j]);
matrix[i][j].value = data[i][j];
matrix[i][j].column = j;
matrix[i][j].row = i;
matrix[i][j].visited = false;
}
printf("\n");
}
}
int main()
{
printMatrix();
int x=0 , y=0;
printf("\nToa do cua o xuat phat la O(0,0).\n");
bool check = false;
do
{
printf("\nHay nhap toa do cua o dich den A: \n");
printf("Nhap dong: ");
scanf("%d",&x);
printf("Nhap cot: ");
scanf("%d",&y);
check = checkCoordinate(x, y);
if (check == false)
{
if ( x<0 || x>8 ) { printf("Gia tri cua dong phai tu 0 den 8!\
n"); }
if ( y<0 || y>8 ) { printf("Gia tri cua cot phai tu 0 den 8!\n");
}
}
} while (check == false);
findShortestPath(x,y);
return 0;
}