Các bài toán này đều là cố định nên khác nhau có lẽ là cách chọn bước đi thôi
Hỏi về Bài toán con mã (The Knight's tour problem), thuật toán quay lui
Mình có làm bài này nhưng băng winform C#. nếu không yêu cầu in ra tất cả các đường đi từ vị trí ban đầu thì có thể áp dụng Heuristic để giải:Đi vào nước mà tại đó khả năng đi tiếp của quân Mã là nhỏ nhất.
Có cần soucre thảm khảo không?
Dạ nếu được thì anh post code giùm ạ, cám ơn anh.
link tải đây(vs2010): https://sites.google.com/site/canhhoanh/files/MaDiTuan.zip?attredirects=0&d=1
bạn ơi có thỉ chỉ mình hướng tìm tất cả đường đi của quân mã khi nhập vào vị trí ban đầu ko c++
4 năm rồi cơ ah @@
Bạn ơi có thể hướng dẫn mình khử cái để quy trong bài đc ko vì mình có bài tập về mã đi tuần chỉ dùng stack. Mong bạn chỉ giúp
Xem bài này có giúp gì cho bạn không?
mình mới học c++ bạn ơi nên chưa biết gì nhiều hướng dẫn mình làm để hiểu đi. Làm sao để dùng stack trong bài mã đi tuần đó z
Bài toán mã đi tuần là bài toán khó, theo kinh nghiệm mình bạn nên chia thành nhiều cấp độ
ví dụ:
cho nó chày phài
cho nó chạy trái
…
cho nó chạy đúng hình chữ nhật
…
Làm từ từ mới hấp dẫn, cái đemo của mình chưa check các vị trí đã đi qua chỉ cho nó chạy ram dom thôi
Còn vấn đề khử đệ qui thì bạn làm theo cách kinh điển như sau
Bạn xem cái link này, nghiên cứu họ đệ qui sao, rồi họ khử thế nào
http://blogitnlu.azurewebsites.net/blogerIT/laptrinh/ltdt/DFS.jsp
hope usefull to you
#include <iostream>
#include <stdio.h>
#include <conio.h>
using namespace std;
#define N 5
#define STMAX N*N
//Định nghĩa cấu trúc cho 1 STACK
struct STACK {
int a[STMAX]; //Mảng các phần tử của ngăn xếp
int top; //Chỉ số phần tử đỉnh đầu của ngăn xếp
};
// Kiểu miêu tả thông tin của 1 bước đi
//Các biến toàn cục được sử dụng
int board[N][N]; //Bảng 6x6
int x, y, newx, newy, move_number, move_type, dem, n;
int main()
{
STACK Horse;
cout << "Nhap kich thuoc ban co:";
InitBoard(n);
InitStack(Horse);
cout << "Nhap toa do diem bat dau (x, y): ";
cin >> x >> y;
board[x][y] = 1; //Điểm bắt đầu
move_number = 2; //điểm đi tiếp theo
do {
find_move(Horse, move_type);
Push(Horse, move_type);
x = newx;
y = newy;
move_type = 0;
board[x][y] = move_number++;
if (move_number > N*N) {
Show();
}
} while (move_number <= N * N );
return 0;
}
//1. Tạo ngăn xếp rỗng
void InitStack(STACK& myStack) {
myStack.top = 1;
}
//2. Kiểm tra ngăn xếp rỗng
int IsEmptyStack(STACK& myStack) {
if (myStack.top == -1) return 1; //Ngăn xếp rỗng
return 0; //Ngăn xếp không rỗng
}
//3. Kiểm tra ngăn xếp đầy hay không?
int IsFullStack(STACK& myStack) {
if (myStack.top == STMAX - 1) return 1; //Ngăn xếp đầy
return 0; //Ngăn xếp chưa đầy
}
//4. Thêm 1 phần tử vào ngăn xếp
void Push(STACK& myStack, int x) {
if (IsEmptyStack(myStack)) cout << "Ngan xep day";
else
{
myStack.a[myStack.top + 1] = x;
myStack.top++;
}
}
//5. Lấy thông tin phần tử ở đỉnh ngăn xếp
int Top(STACK myStack) {
return myStack.a[myStack.top];
}
//6. Trích hủy phần tử ở đỉnh ngăn xếp
int Pop(STACK& myStack) {
int t = myStack.a[myStack.top];
myStack.top--;
return t;
}
//7. Khởi tạo bàn cờ
void InitBoard(int n) //kích thước NxN
{
for (int i = 0; i<n; i++)
for (int j = 0; j<n; j++)
board[i][j] = 0;
}
//9. Kiểm tra xem có đi được hay ko
int move_valid()
{
return ((newx >= 0) && (newx < N) &&
(newy >= 0) && (newy < N) &&
(board[newx][newy] == 0));
}
//10. 8 trường hợp đi của quân mã
void try_move(int mt)
{
switch (mt) {
case 1:
newx = x + 1;
newy = y + 2;
break;
case 2:
newx = x + 2;
newy = y + 1;
break;
case 3:
newx = x + 2;
newy = y - 1;
break;
case 4:
newx = x + 1;
newy = y - 2;
break;
case 5:
newx = x - 1;
newy = y - 2;
break;
case 6:
newx = x - 2;
newy = y - 1;
break;
case 7:
newx = x - 2;
newy = y + 1;
break;
case 8:
newx = x - 1;
newy = y + 2;
break;
default:
cout << "Ko ton tai nuoc di thoa man yeu cau";
exit(1);
}
}
//11.Truy xuất nước đi
void retract_move(STACK& myStack)
{
int mtype;
if (!IsEmptyStack(myStack)) //Kiểm tra stack rỗng
move_type = Pop(myStack); // Nếu ko thì lấy nước đi ra khỏi stack
board[x][y] = 0; //gán lại vị trí bắt đầu
mtype = (move_type + 4) % 8; // gán lại bước đi mới
if (mtype == 0) // kiểm tra bước đi mới
mtype = 8;
try_move(mtype); // Thử bước đi
x = newx; // gán lại vị trí mới
y = newy;
move_number--; // lùi lại số nước đi
}
//12. Tìm nước đi của quân mã
void find_move(STACK& myStack, int& move_type)
{
do {
while (move_type == 8) //Nếu đã đi hết nước đi
{
retract_move(myStack); //Quay lui
}
move_type++;
try_move(move_type); //kiểm tra trường hợp khác để đi tiếp
} while (!move_valid());
}
//8. In kết quả con mã đi trên bàn cờ
void Show() {
int h, c;
printf("Cach di thu : %d\n", ++dem);
for (h = 0; h < N; h++) {
// Hiển thị hàng lưới ngang bàn cờ
for (c = 0; c < N; c++) printf("+----");
printf("+\n");
// Hiển thị nội dung hàng thứ h bàn cờ
for (c = 0; c < N; c++)
printf("| %2d ", board[h][c]);
printf("|\n");
}
// Hiển thị hàng lưới ngang bàn cờ cuối cùng
for (c = 0; c < N; c++) printf("+----");
printf("+\n");
}
Em mới code bài mã đi tuần ngăn xếp này nhưng chỉ mới làm phần in ra 1 đáp án. Ai có thể chỉ em in ra nhiều đáp án từ 1 vị trí bắt đầu ko ạ, mong mọi người giúp đỡ, em tìm mãi trên mạng toàn đệ quy ko có ngăn xếp để tham khảo.
Chào anh,
Em xin phép tham khảo bài “báo cáo mã đi tuần” của anh cho báo cáo đồ án môn của em ạ.
em cảm ơn anh nhiều