1. 程式人生 > 其它 >發現離散數學的小作用

發現離散數學的小作用

迷宮程式

點選檢視迷宮程式程式碼
#include<stdio.h>
#include <stdlib.h>

/*
	迷宮求解 
*/
struct Node {
	int x;
	int y;
	struct Node* prior;
	struct Node* next;
};

struct Stack{
	Node* bottom;
	Node* top;
	int stacksize;
};

// 初始化棧 
Stack* init(); 
// 入棧
void push(Stack* s, int x, int y);
// 出棧
void pop(Stack* s);
// 顯示棧中資料 
void showStack(Stack* stack);
int x,y;
int map[10][10] = {
		{1,1,1,1,1,1,1,1,1,1},
		{1,2,1,0,0,0,0,0,1,1},
		{1,0,1,1,1,1,1,0,1,1},
		{1,0,0,0,1,0,1,0,0,1},
		{1,0,1,0,1,0,0,0,0,1},
		{1,0,1,0,1,1,1,1,1,1},
		{1,1,1,0,1,0,0,0,1,1},
		{1,0,0,0,1,0,1,0,0,1},
		{1,1,0,0,0,0,0,0,0,1},
		{1,1,1,1,1,1,1,1,1,1}
	};
Stack* stack;
int right();
int left();
int up();
int down();

int main() {
	
	x = 1;
	y = 1;
	stack = init();
	//x != 8 && y != 8 錯誤 
	// x != 8 || y != 8 正確
	// x == 8 && y == 8 正確 
	int flag = 1;
	while (flag) {
		printf("\n");
		if (right()) {
			printf("右走\n");
		} else if (left()) {
			printf("左走\n");
		}else if (up()) {
			printf("上走\n");
		}else if (down()) {
			printf("下走\n");
		}else {
			printf("出棧\n");
			pop(stack);
		}
		
		for (int i = 0; i < 10; i++) {
			for (int j = 0; j < 10; j++) {
				int n = map[i][j];
				printf(" %d ", n);
			}
			printf("\n");
		}
		if (x == 8 && y == 8) {
			flag = 0;
		}
		
//		if (right() || left()
//			|| up() || down()) {
//			printf("下一步\n");
//		} else {
//			printf("出棧\n");
//			pop(stack);
//		}
	} 
	return 0;
}

int right() {
	if (map[x][y + 1] != 1 && map[x][y + 1] != 2) {
		y += 1;
		map[x][y] = 2;
		push(stack, x, y);
		return 1;
	}
	return 0;
}
int left() {
	if (map[x][y - 1] != 1 && map[x][y - 1] != 2) {
		y -= 1;
		map[x][y] = 2;
		push(stack, x, y);
		return 1;
	}
	return 0;
}
int up() {
	if (map[x - 1][y] != 1 && map[x - 1][y] != 2) {
		x -= 1;
		map[x][y] = 2;
		push(stack, x, y);
		return 1;
	}
	return 0;
}
int down(){
	if (map[x + 1][y]!= 1 && map[x + 1][y] != 2) {
		x += 1;
		map[x][y] = 2;
		printf("下一步地址;%d", map[x][y]); 
		push(stack, x, y);
		return 1;
	}
	return 0;
}



// 初始化棧 
Stack* init() {
	Stack* stack = (Stack*)malloc(sizeof(Stack));
	stack->stacksize = 100;
	
	Node* head = (Node*)malloc(sizeof(Node));
	head->next = head; 
	head->prior = head;
	stack->bottom = head;
	stack->top = head;
	for (int i = 0; i < stack->stacksize; i++ ) {
		Node* newNode = (Node*)malloc(sizeof(Node));
		newNode->next = head->next;
		head->next->prior = newNode;
		newNode->prior = head;
		head->next = newNode;
	}
	return stack;
}
// 入棧
void push(Stack* stack, int x, int y) {
	if (stack->top->next != stack->bottom) {
		
		stack->top =  stack->top->next;
		stack->top->x = x;
		stack->top->y = y;
	} else {
		printf("棧滿!\n"); 
	}
}
// 出棧
void pop(Stack* stack) {
	if (stack->top != stack->bottom) {
		
		stack->top =  stack->top->prior;
		x = stack->top->x;
		y = stack->top->y;
	} else {
		printf("棧空!\n"); 
	}
}

// 顯示棧中資料 
void showStack(Stack* stack) {
	if (stack->bottom == stack->top) {
		printf("棧為空!");
	}
	else {
		Node* p =  stack->bottom->next;
		printf("當前棧資料為:");
		while (p != stack->top->next) {
			printf("%d  ", p->x);
			printf("%d  ", p->y);
			p = p->next;
		}
	}
	printf("\n");
	printf("\n");
}

判斷是否到達終點時發生錯誤

為真:沒到達終點
為假:到達終點

x != 8 && y != 8 錯誤
x != 8 || y != 8 正確
!(x == 8 && y == 8) 正確

如果是第一個條件,則當x為8或y為8的時候都沒到達終點。第九行和第九列都無法到達。
如果是第二個條件或第三個條件,意思是:當x和y都為8的時候到達終點

發現的技巧

x != 8 && y != 8
的意思直接理解起來可能會理解錯誤,或者不好理解
這時候我們可以使用離散數學中的數理邏輯進行等價轉換

設A:x等於8 設B:y等於8

x != 8 && y != 8
符號化為:┐A ∧ ┐B <=> ┐(A ∨ B) 
意思為:x等於8或y等於8為假時,到達終點
代表第九行和第九列都是終點,而不是(8,8)這個位置是終點

!(x == 8 && y == 8)
這個就比較好理解
意思為:x等於8並且y等於8為假,到達終點
可以等價於:┐(A ∧ B) <=> ┐A ∨ ┐B
意思為:x不等於8或者y不等於8為真

總結

可以使用等價代換去檢查判斷條件是否正確,通過不同的表達方式去理解判斷條件的意思。從而檢查我們是否理解錯誤判斷條件的意思。