数据结构--期末课程设计

/*************************************
* 版权所有(C)2015,罗海员
* 文件名称:main.cpp maze.cpp headfile.h
* 内容摘要:主要内容:  主要内容:分为两大模块,首先以一个爱情故事为主题模块:
 *               某个太空神秘国度中有很多美丽的小村,从太空中可以望见,小村间有路相连,
 *               更精确一点说,任意两村之问有且仅有一条路径。小村A中有位年轻人爱上了
 *               自己村里的美丽姑娘。每天早晨,姑娘都要去小村B里的面包房工作,傍晚6点
 *               回到家。年轻人终于决定要向姑娘表白,他打算在小村C等着姑娘路过的时候
 *               把爱慕说出来。问题是,他不能确定小村C是否在小村B到小村A之间的路径上。
 *               第二大模块:对应于小村子,数据和结构分居两地,远隔千山万水,不能相见,
 *               但是爱情不能阻挡数据,一直打探下落,终于找到了结构的下落。您能帮帮数据,
 *               冲破迷宫,早日与结构相遇吗?
* 其他说明:
* 当前版本:V1.2.8
* 作者:罗海员
* 完成日期:2015.12.21

* 修改记录:12.26日修改格式
* 修改日期:12.26日
*
* 版本号:V1.2.8
* 修改人:罗海员
* 修改内容:
*************************************/


/***************************************************************************************************************
 *               
 *   算法分析:  我们能够注意到条件中有一条“任意两村之间有且仅有一条路径”,这表明这是一棵N个节点的树,
 *               每次查询给定点C是否在其余两点A、B之间的路径上。最直接的解法是沿着A、B点往上找,直到相遇或者碰到C,
 *               不过这样对于全部节点在一条线上的树,每次查询的复杂度是O(N),肯定超时。 
 *               仔细观察,我们可以发现如果点C在A、B之间的路径上,那么它满足下面这个有趣的规律:点C在A、B之间的路径上
 *               当且仅当C仅是A、B其中一个节点的祖先——除了一个非常特殊的情况,就是当C是A、B两点的最低公共祖先时,点C也
 *               在A、B的路径上(其实这道题的关键就是判断这个特殊情况)。因此,我们得到如下的算法:判断点C是否仅是其中
 *               一个节点的祖先。如果是,那么C肯定在路径上(那么就有该青年可以等到这位美丽姑娘);否则,如果C是A、B两点
 *               的共同祖先,则判断C是否为最低公共祖先,如果是,那么C肯定在路径上(那么就有该青年可以等到这位美丽姑娘),
 *               否则C不在路径上(该青年不可以等到这位美丽姑娘)。 
 *               那么现在剩下两个问题: 
 *               (1)如何快速判断一个点是否是另外一个点的祖先? 
 *               (2)如果C是A、B两点的共同祖先,如何快速判断它是否是最低的? 
 *               对于第一个问题,我们可以用图的深度优先搜索遍历一边,记录每一个节点的入栈时间及出栈时间,然后判断其包含关系。
 *               对于每一棵深度优先搜索树我们规定每个节点左下角的数字表示第一次访问该节点即入栈时间,右下角的数字表示离开
 *               该节点即出栈时间。要判断点C是否是点A(B)的祖先,只要判断点C所在的入栈与出栈时间的区间是否包含了点A(B)
 *               所在的入栈与出栈时间的区间即可。 
 *               对于第二个问题,要判断C是否是A和B的最低公共祖先,其实就是看是否有比C更低的祖先,如果有则说明C不是最低的。
 *               我们采取的方法是:如果我们从左到右依次列出C的儿子节点的入栈时间与出栈时间,我们不难发现这个区间数列是递增的!
 *               于是我们只要在这个递增的区间数列中二分查找是否有A、B所在的大区间即可!
 *               
 *   问题描述:
 *             (1)需要建立数据结构,一种方法是建立一个图的邻接表存储结构,另一种方法是建立以孩子兄弟链存储结构的树。
 *                  这里采用的是后者。输入数据建立树采用深度优先遍历建立树。 
 *             (2)树的遍历:从指定的某个定点出发,按照一定的搜索方法对图中的所有各做一次访问的过程,
 *                  本题采用了一个递归过程的深度优先搜索遍历解决了该问题。 
 *             (3)二分法查找,对递增序列区段进行查找,由于每个区间都有小值和大值,只需对所有区间的小值进行查找,
 *                  在对该区间进行比较判断即可。
 *                  
 *   数据及其逻辑结构简单描述:
 *               线性树形图形结构都用上了,其中:
 *               (1)线性:一对一
 *               (2)树形:一对多
 *               (3)图形:多对多建立所有节点之间互相建立联系
 *   
 *   知识点运用:
 *               栈(存取数据)
 *               递归(深度优先)
 *               数组(存储数据)
 *               树(二叉树)
 *               图(存储)
 *               查找(二分查找)
 *
****************************************************************************************************************************/

/********************************
*功能描述:头文件
*输入参数:无
*输出参数:
*返回值:
*其他说明:
*********************************/
#include<string.h>
#include<iomanip>
#include <conio.h>
#define MAXnum 20000

//
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
//#include<graphics.h>
//windows
#include<time.h>
#include <iostream>
#include <windows.h>
using namespace std;
//#include<iostream.h>


/********************************
*功能描述:主函数,主要为爱情故事部分
*输入参数:村子个数
*输出参数:
*返回值:return 0
*其他说明:
*********************************/
#include "headfile.h"
#define SLEEP3 Sleep(3000)
#define CLEAR  "cls"

//定义数组的最大值
#define MAXSIZE 50000
//定义主函数中的函数部分
void printf_menu();     //提供选择的菜单
void mainabout();       //关于设计
void welcome();         //
void saunfa();          //
void system_time();     //调用系统时间
void jindutiao1();      //进度条
void jindutiao2();
void Signout();         //退出
void getPass(char password[7]);
int lovemaze();
int fankui();

//几个结构体
//村子     树节点,数据域有入栈出栈时间域、村子编号域
//树采用   孩子兄弟链存储结构
typedef struct Village
{
	int num;        //村子编号
	int intime;     //深度优先遍历入栈时间
	int outtime;    //节点出栈时间
	struct Village *firstchild;
	struct Village *nextcousin;
}VillageNode;

typedef struct
{
	int top;
	VillageNode *villages[MAXSIZE];
}Stack;

Stack *s ;
int time1=0;     //记录栈访问时间,定义其初始值为零

/********************************
*功能描述:函数的声明
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
void dfs(VillageNode *root);
int addNode(VillageNode *root, int va, int vb);
void ifwait(VillageNode *root, int va, int vb, int vc);
VillageNode* dfsfind(VillageNode* root, int va);
void pushStack(VillageNode *p);                               //将*p节点压入栈
void popStack(VillageNode *p);                                //将栈顶元素弹出,并将地址保存至p指针

//将*p节点压入栈
void pushStack(VillageNode *p)
{
	if(s->top>-1)
		printf("当前栈顶元素为%d,",s->villages[s->top]->num);
	else
		printf("当前栈元素为空,");

	s->villages[++s->top] = p;
	time1++;     //栈访问次数加1
	p->intime = time1;    //记录入栈时间

	printf("入栈后元素总数为%d,入栈元素为%d,intime: %d\n",s->top+1, p->num, time1);

}
//将栈顶元素弹出,并将地址保存至p指针
void popStack(VillageNode *p)
{
	if(s->top > -1)
	{
		p = s->villages[s->top];
		s->top--;
		time1++;         //栈访问次数加1
		p->outtime = time1;

		printf("出栈元素为%d, outtime: %d,出栈后元素总数为%d,",p->num, time, s->top+1);
	}

	if(s->top > -1)
		printf("当前栈顶元素为%d\n",s->villages[s->top]->num);
	else
		printf("当前栈元素为空\n");
}
/********************************
*功能描述:递归遍历树
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
VillageNode* dfsfind(VillageNode* root, int va)
{
	if(root == NULL)    //当当前节点为空时返回NULL
		return NULL;
	int v = root->num;
	VillageNode *p, *q;
	//curcnt++;           //用于记录当前访问过的节点数
	if(va == v )        //如果找到原先既有的节点,则返回该节点的指针
		return root;

	q = dfsfind(root->firstchild, va);  //递归访问孩子节点
	if(q != NULL)
		return q;

	//依次递归访问兄弟节点
	p = root->nextcousin;
	while(p != NULL)
	{
		q = dfsfind(p, va);

		if(q != NULL)
			return q;

		p = p->nextcousin;
	}

	return NULL;
}

/**************va必须是树中已经存在的节点****************************/
int addNode(VillageNode *root, int va, int vb)
{
	VillageNode *vp = dfsfind(root, va);   //寻找编号为a的村子
	VillageNode *p, *q;
	if(vp != NULL)
	{
		if(vp->num == va)     //找到村子va,遍历其孩子节点
		{
			p = vp->firstchild;
			q = vp;
			if(p == NULL)   //当vp节点下没有孩子节点时,为村子vb建立孩子接点vp
			{
				VillageNode *vn = (VillageNode*) malloc(sizeof(VillageNode));
				vn->firstchild = NULL;
				vn->nextcousin = NULL;
				vn->num = vb;
				q->firstchild = vn;
				return 1;
			}
			//当vp节点下有孩子节点时,找到最后一个孩子节点或已存在时返回0
			while(p != NULL)
			{
				if(p->num == vb)     //当村子a存在到村子b的路时返回0
					return 0;
				q = p;              //记录下当前节点
				p = p->nextcousin;  //p指向下一个节点
			}
			//为最后一个孩子添加兄弟节点vn(vb村子)
			VillageNode *vn = (VillageNode*) malloc(sizeof(VillageNode));
			vn->firstchild = NULL;
			vn->nextcousin = NULL;
			vn->num = vb;
			q->nextcousin = vn;
			return 1;
		}
	}
	return -1;
}
/********************************
*功能描述:销毁节点,释放空间
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
void destroyTree(VillageNode *root)
{
	VillageNode *p;
	p = root->firstchild;  //指向第一个孩子
	while(p != NULL)    //当孩子节点不为空时,递归访问孩子节点
	{
		destroyTree(p);
		p = p->nextcousin;
	}
	free(root);
	return;
}

/********************************
*功能描述:深度优先搜索遍历
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
void dfs(VillageNode *root)
{
	pushStack(root);
	VillageNode *p;
	p = root->firstchild;  //指向第一个孩子
	while(p != NULL)    //当孩子节点不为空时,递归访问孩子节点
	{
		dfs(p);
		p = p->nextcousin;
	}
	popStack(p);    //弹出栈顶元素
	return;
}

/********************************
*功能描述:查找
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
void ifwait(VillageNode *root, int va, int vb, int vc)
{
	VillageNode *VA = dfsfind(root,va);
	VillageNode *VB = dfsfind(root,vb);
	VillageNode *VC = dfsfind(root,vc);
	if(VA == NULL || VB == NULL || VC == NULL)
	{
		printf("你是不是记错了哦?不存在编号为");
		if(VA == NULL)
			printf("%d",va);
		if(VB == NULL)
			printf("、%d",vb);
		if(VC == NULL)
			printf("、%d",vc);
		printf("的村子哦!\n");
		return;
	}
	if((VC->intime <= VA->intime && VC->outtime >= VA->outtime)       //当VC节点的入出栈时间区间包含VA的区间
		&&(VC->intime <= VB->intime && VC->outtime >= VB->outtime))    //且VC节点的入出栈时间区间包含VB的区间
	{
		//当VC是VA和VB的公共祖先时判断是否是最低公共祖先
		int a[2][MAXSIZE];  //二维数组第一行存放intime 第二行存放outtime 每一列对应一个节点 从左到右
		int m,n;
		m = VA->intime <= VB->intime ? VA->intime : VB->intime;  //记录VA、VB入栈的最小时间
		n = VA->outtime >= VB->outtime ? VA->outtime : VB->outtime;  //记录VA、VB出栈最大时间
		VillageNode *p = VC->firstchild;
		int i=0;
		while(p != NULL)    //遍历VC节点所有的孩子节点 将孩子们的入出栈时间存入数组,方便二分查找
		{
			a[0][i] = p->intime;
			a[1][i] = p->outtime;
			i++;
			p = p->nextcousin;
		}
		//二分查找[m,n]区间是否包含在其中一个孩子节点中
		int low=0, high = i-1, mid;
		while(low <= high)
		{
			mid = (low + high) / 2;
			if(a[0][mid] <= m && a[1][mid] >= n)  //查找到有区间包含[m,n]区间时,说明VC不是VA和VB的最低公共祖先,则跳出循环
			{
				printf("一定是姿势不对!百尺竿头需努力,赢得芳心是目标。\n\n");
				return;
			}

			if(a[0][mid] > m)   //继续在a[0][low...mid-1]中查找
				high = mid - 1;
			else                //继续在a[0][mid+1...high]中查找
				low = mid + 1;
		}
		printf("皇天不负苦心人,终于让我等到你!赶快去表白!\n\n");    //当查找结束仍没有找到该区间,说明VC是VA。VB的最低公共祖先
	}
	else if((VC->intime <= VA->intime && VC->outtime >= VA->outtime)  //当VC节点的入出栈时间区间包含VA的区间
		|| (VC->intime <= VB->intime && VC->outtime >= VB->outtime))  //或VC节点的入出栈时间区间包含VB的区间
	{
		//此时VC是VA、VB其中一个节点的祖先,存在A-C-B的路径
		printf("皇天不负苦心人,终于让我等到你!赶快去表白!\n\n");
	}
	else        //当VC不是VA或VB节点的祖先时不存在A-C-B的路径
		printf("一定是姿势不对!百尺竿头需努力,赢得芳心是目标。\n\n");

	return;
}

/********************************
*功能描述:主函数
*输入参数:
*输出参数:
*返回值:return 0
*其他说明:
*********************************/
int main()
{
	system("title ★数据结构课程设计最终版★神秘国度的爱情故事【版本号:V1.2.8 罗海员】");
	//system("Color 3A");
	clock_t start,finish;
	double totaltime;
	start=clock();

	void mainabout();
	void welcome();
	void mainmenu();
	welcome();
	//加载
	cout<<"\n\n\n\n\n\n\n\n\t\t\t\t加载中\n\n"<<endl;
	int m;
	cout<<"加载中,请稍后";
	for(m=1;m<=3;m++)
	{
		cout<<"*";
		Sleep(200);
	}
	cout<<endl;
	int n;
	for(n=1;n<=40;n++)
	{
		cout<<"▉";
		Sleep(50);
	}
	system(CLEAR);

	char userName[9]="";
	char userMima[7]="";
	int i;

	for(i=1;i<4;i++)
	{
		cout<<"管理员请登录"<<endl;
		cout<<endl<<"\t\t\t请输入管理员姓名:";
		cin>>userName;
		cout<<"\t\t\t请输入您的密码:";
		cin>>userMima;
		//		getPass(userMima);
		if(strcmp(userName,userMima)==0)
		{
			system("cls");
			jindutiao1();
		}
		if((strcmp(userName,"admin")==0)&&(strcmp(userMima,"admin")==0))
		{
			mainmenu();
		}
		else
		{
			if(i<3)
			{
				cout<<"用户名或密码错误,请重新输入!"<<endl;
			}
			else
			{
				cout<<"用户名或密码错误,退出系统!"<<endl;
			}
		}
	}
	finish=clock();
	totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
	cout<<"\n此程序的运行时间为"<<totaltime<<"秒!"<<endl;
	cout<<"感谢光临!"<<endl;

	return 0;
}

//进度条
void jindutiao1()
{
	int n1;
	cout<<"\n\n\n\n\n\n\n\n\t\t\t\t正在登陆\n\n"<<endl;

	for(n1=1;n1<8;n1++)
	{
		cout<<"███";
		Sleep(100);
	}
	for(n1=1;n1<5;n1++)
	{
		cout<<"████";
		Sleep(200);
	}
	for(n1=1;n1<4;n1++)
	{
		cout<<"█";
		Sleep(300);
	}
}
void jindutiao2(){}

/*********************开始**********************/
void mainstart()
{
	system("color f9");
	int N, M, a, b, c;

	system_time();        //调用系统时间

	printf("\t\t\t********神秘国度的爱情故事********\n\n");
	printf("请输入小村个数:\n>");
	scanf("%d",&N);
	VillageNode *root = (VillageNode *)malloc(sizeof(VillageNode));     //开辟指向深度优先搜索树的指针并建立深度优先搜素树
	root->firstchild = NULL;
	root->nextcousin = NULL;
	root->num = 0;

	printf("接下来,请依次输入包含一条双向道路的两个端点小村的编号:\n");
	while(--N)
	{
		printf(">");
		while(getchar() != '\n');       //清除缓冲区
		scanf("%d %d", &a, &b);         //读取边信息
		int flag = addNode(root, a, b);
		if(flag==0)
		{
			printf("小村%d到小村%d的路径已存在,无需再次输入,本次输入将不会被记录。\n", a, b);
			N++;
		}
		else if(flag == 1)
			printf("成功录入!%d-%d\n", a, b);
		else
			printf("录入失败!%d-%d\n", a, b);
	}
	printf("\n下面输出的是整棵树的遍历过程,你可以无需理会,3秒后自动删除。\n");
	printf("--------------------------------------------------------------------------\n");
	s = (Stack *)malloc(sizeof(Stack));         //初始化栈空间
	s->top = -1;    //初始化栈顶元素为空
	dfs(root);      //深度优先遍历一遍树
	printf("--------------------------------------------------------------------------\n");
	SLEEP3;      //宏定义函数 实现暂停3秒
	system(CLEAR);          //清除屏幕
	printf("\t\t\t********神秘国度的爱情故事********\n\n");
	printf("下面将进行测试,输入A、B、C三个村子的编号,这将决定你能否在C村等到心仪的姑娘。\n");
	printf("请输入测试样例个数(提示:当输入的测试样例个数为0时测试结束):\n>");
	while(getchar() != '\n');       //清除缓冲区
    while(scanf("%d", &M) && M > 0)
	{
		printf("下面请依次输入测试样例:\n");
		int i=0;
		while(M--)
		{
			printf("第%d组:>", ++i);
			while(getchar() != '\n');      //清除缓冲区
			scanf("%d %d %d", &a, &b, &c);
			ifwait(root, a, b, c);
		}
		printf("请输入测试样例个数:\n>");
		while(getchar() != '\n');          //清除缓冲区
	}
	printf("\n经过这么多的测试,你找到在哪个村子可以等到她了吗?");
	printf("如果找到了,那么祝福你表白成功哦!如果你还没有找到,");
	printf("你的运气也忒差了点!再次运行本程序,再努力试试!成功就在你面前!\n");
	free(s);                               //释放栈空间
	destroyTree(root);                     //释放树的每个节点空间
}

//调用系统时间
void system_time()
{
	system(CLEAR);
	time_t rawtime;
	struct tm * timeinfo;
	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	printf ( "\t\tCurrent local time and date: %s", asctime (timeinfo) );
}

//选择菜单,提供给用户的界面
void printf_menu()
{
	cout<<endl;
	cout<<"◇═══════════════════════════════◇"<<endl;
	cout<<"◇                             MENU                             ◇"<<endl;
	cout<<"◇═══════════════════════════════◇"<<endl;
	cout<<"◇○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○◇"<<endl;
	cout<<"◇****开始追求 请按<1>                      了解规则 请按<2>****◇"<<endl;
	cout<<"◇****算法实现 请按<3>                      本次设计 请按<4>****◇"<<endl;
	cout<<"◇═══════════════════════════════◇"<<endl;
	cout<<"◇                                                              ◇"<<endl;
	cout<<"◇以下为扩展的内容,可自行选择进入:                              ◇"<<endl;
	cout<<"◇****爱情迷宫 请按<5>                      反馈信息 请按<6>****◇"<<endl;
	cout<<"◇═══════════════════════════════◇"<<endl;
	cout<<"请输入您的选择:"<<endl;
}

/**********************主菜单,函数运算**************************/
void mainmenu()
{
	system("cls");
	system("color A");
	int choice;
	do
	{
		printf_menu();
		cin>>choice;
		switch(choice)
		{
		case 0:
			break;
		case 1:
			mainstart();
			break;
		case 2:
			mainabout();
			break;
		case 3:
			saunfa();
			break;
		case 4:
			Signout();
			break;
		case 5:
			lovemaze();
			break;

		default:
			cout<<"无效选项!"<<endl;
			break;
		}
	}
	while(choice!=0);
}
//密码转换
//将输进去的密码转化为*
void getPass(char password[7])
{
	char ch;
	int i=0;
	while(i<6)
	{
		ch=getchar();
		if(ch>='0'&&ch<='9')
		{
			putchar('*');
			password[i]=ch;
			i++;
		}
	}
}


//欢迎界面
void welcome()
{
	system("cls");
	cout<<endl<<"★●   ●●   ●●   ●●   ●●   ○   ●●   ●●   ●●   ●●   ●●   ●★"<<endl<<endl;
	cout<<"                       欢迎进入罗海员版美丽的爱情故事                         "<<endl<<endl;
	cout<<"★●   ●●   ●●   ●●   ●●   ○   ●●   ●●   ●●   ●●   ●●   ●★"<<endl;
}

//退出
void Signout()
{
	cout<<"|----------------------------------------|"<<endl;
	cout<<"|         最终解释权归罗海员所有         |"<<endl;
	cout<<"|           时间:11.10-12.24             |"<<endl;
	cout<<"|             欢迎下次光临               |"<<endl;
	cout<<"|----------------------------------------|"<<endl;
}

/***********************简介*************************/
void mainabout()
{
	system("cls");
	cout<<"1内容"<<endl;
	cout<<"某个太空神秘国度中有很多美丽的小村,从太空中可以望见,小村间有路相连,更精确一点说,任意两村之问有且仅有一条路径。"<<endl;
	cout<<"小村A中有位年轻人爱上了自己村里的美丽姑娘。每天早晨,姑娘都要去小村B里的面包房工作,傍晚6点回到家。年轻人终于决定要向姑娘表白,"<<endl;
	cout<<"他打算在小村C等着姑娘路过的时候把爱慕说出来。问题是,他不能确定小村C是否在小村B到小村A之间的路径上。你可以帮他解决这个问题吗?"<<endl;
}
void saunfa()
{
	system("cls");
	cout<<"算法分析"<<endl;
	cout<<"我们能够注意到条件中有一条“任意两村之间有且仅有一条路径”,这表明这是一棵N个节点的树,每次查询给定点C是否在其余两点A、B之间的路径上。"<<endl;
	cout<<"最直接的解法是沿着A、B点往上找,直到相遇或者碰到C,不过这样对于全部节点在一条线上的树,每次查询的复杂度是O(N),肯定超时。 "<<endl;
	cout<<"仔细观察,我们可以发现如果点C在A、B之间的路径上,那么它满足下面这个有趣的规律:点C在A、B之间的路径上当且仅当C仅是A、B其中一个节点的祖先——除了一个非常特殊的情况,";
	cout<<"就是当C是A、B两点的最低公共祖先时,点C也在A、B的路径上(其实这道题的关键就是判断这个特殊情况)。因此,我们得到如下的算法:"<<endl;
	cout<<"判断点C是否仅是其中一个节点的祖先。如果是,那么C肯定在路径上(那么就有该青年可以等到这位美丽姑娘);否则,如果C是A、B两点的共同祖先,";
	cout<<"则判断C是否为最低公共祖先,如果是,那么C肯定在路径上(那么就有该青年可以等到这位美丽姑娘),否则C不在路径上(该青年不可以等到这位美丽姑娘)。"<<endl;
	cout<<"那么现在剩下两个问题: "<<endl;
	cout<<"(1)如何快速判断一个点是否是另外一个点的祖先? "<<endl;
	cout<<"(2)如果C是A、B两点的共同祖先,如何快速判断它是否是最低的? "<<endl;
	cout<<"对于第一个问题,我们可以用图的深度优先搜索遍历一边,记录每一个节点的入栈时间及出栈时间,然后判断其包含关系。"<<endl;
	cout<<"对于每一棵深度优先搜索树我们规定每个节点左下角的数字表示第一次访问该节点即入栈时间,右下角的数字表示离开该节点即出栈时间。"<<endl;
	cout<<"要判断点C是否是点A(B)的祖先,只要判断点C所在的入栈与出栈时间的区间是否包含了点A(B)所在的入栈与出栈时间的区间即可。 "<<endl;
	cout<<"对于第二个问题,要判断C是否是A和B的最低公共祖先,其实就是看是否有比C更低的祖先,如果有则说明C不是最低的。我们采取的方法是:"<<endl;
	cout<<"如果我们从左到右依次列出C的儿子节点的入栈时间与出栈时间,我们不难发现这个区间数列是递增的!"<<endl;
	cout<<"于是我们只要在这个递增的区间数列中二分查找是否有A、B所在的大区间即可!"<<endl;
}

/********************************
*功能描述:主要包含迷宫函数的算法分析
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/

#include "headfile.h"

int n = 0;
static int i = 0, j = 0;
int x = 1;

#define ERROR 0
#define OVERFLOW 0
#define UNDERFLOW 0
#define OK 1
#define MAX_ARRAY_DIM 3
#define STACKINCREMENT 10
#define STACK_INIT_SIZE 50

typedef int SElemType;
typedef int ElemType;
typedef   struct
{
	SElemType *base;
	SElemType *top;
	int stackSize;
}sqStack;
typedef struct      //坐标,走迷宫时用
{
	int x;
	int y;
}*Pos;
typedef struct Node //存储路线坐标
{
	Pos data;
	Node *next;
}Node, *LinkType;
typedef struct      //存储路线
{
	LinkType top;
	LinkType base;
	int size;
}*Stack;

int visit(int, int);
void make_maze(int**, int);
void Initarray(int **e, int n);
int InitStack(sqStack *s);  //初始化栈,分配50个容量的栈
int Deep_F_S(int **arra_y);
void Push(sqStack *s, ElemType e);
int Pop(sqStack *s);
int text(int **maze, int n);
void print_maze(int **p, int n);
void print_li(int **maze, int n);
void print_num(int**maze, int n);
void print_zf(int **maze, int n);
int road(int **maze, int n);//检测是否有路
//int Maze_Path(int **maze, int n, Pos start, Pos end);
int control(char ch);
int Game(int**maze, int n);
void gotoxy(int x, int y);
int Get_n(int **p);

sqStack  *visited_x = (sqStack*)malloc(sizeof(sqStack));
sqStack  *visited_y = (sqStack*)malloc(sizeof(sqStack));

/********************************
*功能描述:以下为函数的定义与算法的写入
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
void make_maze(int **maze, int n)
{
	int i = 0, j = 0;
	int a = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{

			if (i % 2 == 1 && j % 2 == 1)
				maze[i][j] = 0;
			else
				maze[i][j] = 1;
		}
	}
	InitStack(visited_x);
	InitStack(visited_y);

	time_t t;
	srand((unsigned)time(&t));
	a += (int)(rand());//随机生成起点
	switch (a)
	{
		case 0:
			i = (n - 1) / 2; j = (n - 1) / 2; 
			break;
		case 1:
			i = (n - 1) / 2 - 2; j = (n - 1) / 2; 
			break;
		case 2:
			i = (n - 1) / 2 + 2; j = (n - 1) / 2; 
			break;
		case 3:
			i = (n - 1) / 2; j = (n - 1) / 2 - 2;
			break;
		case 4:
			i = (n - 1) / 2; j = (n - 1) / 2 + 2; 
			break;
	}
	Push(visited_x, i);
	Push(visited_y, j); //生成起点入栈
	Deep_F_S(maze);
}

/********************************
*功能描述:打印迷宫
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
void print_maze(int**maze, int n)
{
	//输出迷宫
	int a = 3;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{
			if (maze[i][j] == 4)
				maze[i][j] = 0;
		}
	}
PR:
	printf("please choose the style you want:\n1 :¤\n2 :╔\n3 : 0、1、2\n");
	scanf_s("%d", &a);
	switch (a)
	{
		case 1: 
			system("cls"); print_zf(maze, n); 
			break;
		case 2: 
			system("cls"); print_li(maze, n); 
			break;
		case 3: 
			system("cls"); print_num(maze, n); 
			break;
		default:
			system("cls"); printf("please input correct choise!\n"); 
			goto PR;
	}

	gotoxy(4, 2);
	printf("◎");
	gotoxy(2 * n - 2, n - 1);
	printf("♂");
	printf("\n\n");
}
void print_zf(int **maze, int n)
{
	int m, o;
	printf("\n");
	for (m = 0; m < n; m++)
	{
		printf("  ");
		for (o = 0; o < n; o++)
		{
			switch (maze[m][o])
			{
			case 1: printf("¤"); break;
			case 0:printf("  "); break;
			case 2:printf("+ "); break;
			}
		}
		printf("\n");
	}
	printf("\n");
}

/********************************
*功能描述:计算迷宫边长
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
void print_num(int**maze, int n)
{
	int m, o;
	printf("\n");
	for (m = 0; m < n; m++)
	{
		printf("  ");
		for (o = 0; o < n; o++)
		{
			printf("%d ", maze[m][o]);
		}
		printf("\n");
	}
	printf("\n");
}

/********************************
*功能描述:打印迷宫的框架
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
void print_li(int **maze, int n)
{
	int m = 0, o = 0;
	printf("\n");
	for (m = 0; m < n; m++)
	{
		printf("  ");
		for (o = 0; o < n; o++)
		{
			if (m == 0 && o == 0)
				printf("╔");
			else if (m == n - 1 && o == n - 1)
				printf("╝");
			else if (m == 0 && o == n - 1)
				printf("╗");
			else if (m == n - 1 && o == 0)
				printf("╚");
			else if (o == 0 && m>0 && m < n - 1)
			{
				if (maze[m][o + 1] != 1)
					printf("║");
				else
					printf("╠");
			}
			else if (o == n - 1 && m>0 && m < n - 1)
			{
				if (maze[m][o - 1] != 1)
					printf("║");
				else
					printf("╣");
			}
			else if (m == 0 && o>0 && o < n - 1)
			{
				if (maze[m + 1][o] != 1)
					printf("═");
				else
					printf("╦");
			}
			else if (m == n - 1 && o>0 && o < n - 1)
			{
				if (maze[m - 1][o] != 1)
					printf("═");
				else
					printf("╩");
			}
			else if (m>0 && o > 0 && m < n - 1 && o < n - 1)//除了四周
			{
				if (maze[m][o] == 1)
				{
					if (maze[m - 1][o] == 1 && maze[m][o - 1] == 1 && maze[m + 1][o] != 1 && maze[m][o + 1] != 1)//上左下右
						printf("╝");
					if (maze[m - 1][o] == 1 && maze[m][o - 1] != 1 && maze[m + 1][o] != 1 && maze[m][o + 1] == 1)
						printf("╚");
					if (maze[m - 1][o] != 1 && maze[m][o - 1] != 1 && maze[m + 1][o] == 1 && maze[m][o + 1] == 1)
						printf("╔");
					if (maze[m - 1][o] != 1 && maze[m][o - 1] == 1 && maze[m + 1][o] == 1 && maze[m][o + 1] != 1)
						printf("╗");
					if (maze[m - 1][o] != 1 && maze[m][o - 1] != 1 && maze[m + 1][o] != 1 && maze[m][o + 1] == 1)
						printf("═");
					if (maze[m - 1][o] != 1 && maze[m][o - 1] == 1 && maze[m + 1][o] != 1 && maze[m][o + 1] != 1)
						printf("═");
					if (maze[m - 1][o] == 1 && maze[m][o - 1] != 1 && maze[m + 1][o] != 1 && maze[m][o + 1] != 1)
						printf("║");
					if (maze[m - 1][o] != 1 && maze[m][o - 1] != 1 && maze[m + 1][o] == 1 && maze[m][o + 1] != 1)
						printf("║");
					if (maze[m - 1][o] == 1 && maze[m][o - 1] == 1 && maze[m + 1][o] == 1 && maze[m][o + 1] == 1)
						printf("╬");
					if (maze[m - 1][o] == 1 && maze[m + 1][o] == 1)//上下是墙
					{
						if (maze[m][o - 1] == 1 && maze[m][o + 1] != 1)
							printf("╣");
						else if (maze[m][o + 1] == 1 && maze[m][o - 1] != 1)
							printf("╠");
						else if (maze[m][o + 1] != 1 && maze[m][o - 1] != 1)
							printf("║");
					}
					if (maze[m][o - 1] == 1 && maze[m][o + 1] == 1)//左右是墙
					{
						if (maze[m - 1][o] == 1 && maze[m + 1][o] != 1)
							printf("╩");
						else if (maze[m + 1][o] == 1 && maze[m - 1][o] != 1)
							printf("╦");
						else if (maze[m + 1][o] != 1 && maze[m - 1][o] != 1)
							printf("═");
					}
				}
			}
			if (maze[m][o] == 0)
				printf("  ");
			else if (maze[m][o] == 2)
				printf("* ");
		}
		printf("\n");
	}
	printf("\n");
}

/********************************
*功能描述:从键盘读出操作并运行
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
int Deep_F_S(int **maze)
{
	S:while (x == 0)
	  {
		  goto X;
	  }
	  int i = 1;
	  int j = 1;
	X: x = 0;
	  int a = 0; //在随机数时用作存储容器
	IF:
	  if (i == 1 && j == 1 && (maze[i + 2][j] == 0 || maze[i][j + 2] == 0))
	  { //左上
		  if (maze[i][j + 2] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i][j + 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j += 2;
		  }
		  else
		  {
			  maze[i][j] = 2;
			  maze[i + 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i += 2;
		  }
		  goto IF;
	  }
	  else if (i == 1 && j == 1)  //上一条语句执行失败才会执行这条语句
	  {
		  goto AA;
	  }
	  if (i == n - 2 && j == n - 2 && (maze[n - 4][n - 2] == 0 || maze[n - 2][n - 4] == 0))
	  {//右下
		  if (maze[n - 2][n - 4] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i][j - 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j -= 2;
		  }
		  else
		  {
			  maze[i][j] = 2;
			  maze[i - 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i -= 2;
		  }
		  goto IF;
	  }
	  else if (i == n - 2 && j == n - 2)
	  {
		  goto AA;
	  }
	  if (i == 1 && j == n - 2 && (maze[i + 2][j] == 0 || maze[i][j - 2] == 0))
	  {//右上
		  if (maze[i + 2][j] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i + 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i += 2;
		  }
		  else
		  {
			  maze[i][j] = 2;
			  maze[i][j - 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j -= 2;
		  }
		  goto IF;
	  }
	  else if (i == 1 && j == n - 2)
	  {
		  goto AA;
	  }
	  if (i == n - 2 && j == 1 && (maze[i - 2][j] == 0 || maze[i][j + 2] == 0))
	  {//左下
		  if (maze[i - 2][j] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i - 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i -= 2;
		  }
		  else
		  {
			  maze[i][j] = 2;
			  maze[i][j + 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j += 2;
		  }
		  goto IF;
	  }
	  else if (i == n - 2 && j == 1)
	  {
		  goto AA;
	  }
	  if (i == 1 && (maze[i + 2][j] == 0 || maze[i][j - 2] == 0 || maze[i][j + 2] == 0))
	  {//上
		  if (maze[i + 2][j] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i + 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i += 2;
			  goto IF;
		  }
		  else if (maze[i][j + 2] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i][j + 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j += 2;
			  goto IF;
		  }
		  else if (maze[i][j - 2] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i][j - 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j -= 2;
			  goto IF;
		  }
		  else
			  printf("ERROR");
	  }
	  else if (i == 1)
	  {
		  goto AA;
	  }
	  if (i == n - 2 && (maze[i - 2][j] == 0 || maze[i][j - 2] == 0 || maze[i][j + 2] == 0))
	  {//下
		  if (maze[i - 2][j] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i - 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i -= 2;
			  goto IF;
		  }
		  else if (maze[i][j - 2] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i][j - 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j -= 2;
			  goto IF;
		  }
		  else if (maze[i][j + 2] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i][j + 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j += 2;
			  goto IF;
		  }
		  else
			  printf("ERROR");
	  }
	  else if (i == n - 2)
	  {
		  goto AA;
	  }
	  if (j == 1 && (maze[i][j + 2] == 0 || maze[i - 2][j] == 0 || maze[i + 2][j] == 0))
	  {//左
		  if (maze[i][j + 2] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i][j + 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j += 2;
			  goto IF;
		  }
		  else if (maze[i - 2][j] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i - 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i -= 2;
			  goto IF;
		  }
		  else if (maze[i + 2][j] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i + 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i += 2;
			  goto IF;
		  }
		  else
			  printf("ERROR");
	  }
	  else if (j == 1)
	  {
		  goto AA;
	  }
	  if (j == n - 2 && (maze[i][j - 2] == 0 || maze[i - 2][j] == 0 || maze[i + 2][j] == 0))
	  {//右
		  if (maze[i][j - 2] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i][j - 1] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  j -= 2;
			  goto IF;
		  }
		  else if (maze[i + 2][j] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i + 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i += 2;
			  goto IF;
		  }
		  else if (maze[i - 2][j] == 0)
		  {
			  maze[i][j] = 2;
			  maze[i - 1][j] = 0;
			  Push(visited_x, i);
			  Push(visited_y, j);
			  i -= 2;
			  goto IF;
		  }
		  else
			  printf("ERROR");
	  }
	  else if (j == n - 2)
	  {
		  goto AA;
	  }
	  if (maze[i + 2][j] == 0 || maze[i - 2][j] == 0 || maze[i][j - 2] == 0 || maze[i][j + 2] == 0)
	  {
	SW:
		  a = (int)rand() % 4; // 生成随机数

		  switch (a)
		  {
		  case 0:
			  {
				  if (maze[i - 2][j] == 0) //up
				  {
					  maze[i][j] = 2;
					  maze[i - 1][j] = 0;
					  Push(visited_x, i);
					  Push(visited_y, j);
					  i -= 2;
					  goto IF;
				  }
				  else
					  goto SW;  //随机种子

			  }     break;
		  case 1:
			  {
				  if (maze[i][j - 2] == 0)//left
				  {
					  maze[i][j] = 2;
					  maze[i][j - 1] = 0;
					  Push(visited_x, i);
					  Push(visited_y, j);
					  j -= 2;
					  goto IF;
				  }
				  else
					  goto SW;  //随机种子
			  }   break;
		  case 2:
			  {
				  if (maze[i + 2][j] == 0)//down
				  {
					  maze[i][j] = 2;
					  maze[i + 1][j] = 0;
					  Push(visited_x, i);
					  Push(visited_y, j);
					  i += 2;
					  goto IF;
				  }
				  else
					  goto SW;  //随机种子
			  }   break;
		  case 3:
			  {
				  if (maze[i][j + 2] == 0)
				  {
					  maze[i][j] = 2;
					  maze[i][j + 1] = 0;
					  Push(visited_x, i);
					  Push(visited_y, j);
					  j += 2;
					  goto IF;
				  }
				  else
					  goto SW;  //随机种子
			  } break;
		  default: printf("ERROR");
		  }

	  }
	AA:while (text(maze, n) == 0)
	   {
		   maze[i][j] = 2;
		   i = Pop(visited_x);
		   j = Pop(visited_y);
		   goto S;
	   }
	   for (i = 0; i < n; i++)
	   {
		   for (j = 0; j < n; j++)
		   {
			   if (maze[i][j] == 2)
				   maze[i][j] = 0;
		   }
	   }

	   return OK;
}
//初始化栈,分配50个容量的栈
int InitStack(sqStack *s)  //初始化栈,分配50个容量的栈
{

	s->base = (ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType));
	if (!(s->base))
		exit(0);   // 表示正常退出
	s->top = s->base;
	s->stackSize = STACK_INIT_SIZE;
	return OK;
}
//压栈
void Push(sqStack *s, ElemType e)
{
	// 如果栈满,追加空间
	if ((s->top - s->base) >= (s->stackSize))
	{
		s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
		if (!s->base)
			exit(0);

		s->top = s->base + s->stackSize;              // 设置栈顶
		s->stackSize = s->stackSize + STACKINCREMENT; // 设置栈的最大容量
	}

	*((*s).top) = e;
	s->top++;
}
/********************************
*功能描述:出栈
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
int Pop(sqStack *s)
{
	ElemType *e;
	e = (ElemType*)malloc(sizeof(ElemType));
	if (s->top == s->base)
		return 0;
	*e = *--(s->top);   // 将栈顶元素弹出并修改栈顶指针
	return *e;
}
/********************************
*功能描述:测试数据
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
int text(int **maze, int n)
{
	int i = 0, j = 0, a = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{
			if (i % 2 == 1 && j % 2 == 1 && maze[i][j] == 0)
				return 0;
		}
	}
	return OK;
}
/********************************
*功能描述:迷宫路径
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
int Maze_Path(int **maze, int n, Pos start, Pos end)//如果是向左走了一步,那就一定会退回来,这个要控制刚过来的地方不能回去;
{
	visited_x->top = visited_x->base;
	visited_y->top = visited_y->base;
	Pos now;
	now = (Pos)malloc(sizeof(Pos));
	now->x = start->x;
	now->y = start->y;
	do
	{
		while (maze[now->x + 1][now->y] == 0 || maze[now->x][now->y + 1] == 0 ||
			maze[now->x - 1][now->y] == 0 || maze[now->x][now->y - 1] == 0)//如果有一个方向可通
		{
			if (maze[now->x + 1][now->y] == 0) //如果下边可通
			{
				maze[now->x][now->y] = 2; //留下足迹
				Push(visited_x, now->x);
				Push(visited_y, now->y);
				now->x++;
				if (now->x == end->x && now->y == end->y)
				{
					maze[now->x][now->y] = 2; //留下足迹
					return OK;
				}
				else
					continue;
			}
			if (maze[now->x][now->y + 1] == 0) //如果右边可通
			{
				maze[now->x][now->y] = 2; //留下足迹
				Push(visited_x, now->x);
				Push(visited_y, now->y);
				now->y++;
				if (now->x == end->x && now->y == end->y)
				{
					maze[now->x][now->y] = 2; //留下足迹
					return OK;
				}
				else
					continue;
			}
			if (maze[now->x][now->y - 1] == 0) //如果左边可通
			{
				maze[now->x][now->y] = 2; //留下足迹
				Push(visited_x, now->x);
				Push(visited_y, now->y);
				now->y--;
				if (now->x == end->x && now->y == end->y)
				{
					maze[now->x][now->y] = 2; //留下足迹
					return OK;
				}
				else
					continue;
			}
			if (maze[now->x - 1][now->y] == 0) //如果上边可通
			{
				maze[now->x][now->y] = 2; //留下足迹
				Push(visited_x, now->x);
				Push(visited_y, now->y);
				now->x--;
				if (now->x == end->x && now->y == end->y)
				{
					maze[now->x][now->y] = 2; //留下足迹
					return OK;
				}
				else
					continue;
			}
		}
		maze[now->x][now->y] = 4; //进了死胡同,则……
		now->x = Pop(visited_x);
		now->y = Pop(visited_y);
	} while (now->x != start->x&&now->y != start->y);
	return ERROR;
}

/********************************
*功能描述:函数运行
*输入参数:
*输出参数:
*返回值:
*其他说明:
*********************************/
int Game(int**maze, int n)
{
	int a = 0;
	system("cls");
	printf("◇═══════════════════════════════◇\n");
	printf("◇                         DIRECTION                            ◇\n");
	printf("◇═══════════════════════════════◇\n");
	printf("◇--------                  ↑↓←→                   ---------◇\n");
	printf("◇--------                  HELP: F1                   ---------◇\n");
	printf("◇--------                  QUIT: ESC                  ---------◇\n");
	printf("◇═══════════════════════════════◇\n");
	system("pause");
	system("cls");
	print_maze(maze, n);

	char ch = '0';
	Pos now;
	Pos start;
	Pos end;
	now = (Pos)malloc(sizeof(Pos));
	now->x = 1;
	now->y = 1;//起点位置
	start = (Pos)malloc(sizeof(Pos));
	start->x = 1;
	start->y = n - 2;
	end = (Pos)malloc(sizeof(Pos));
	end->x = n - 2;
	end->y = n - 2;

	gotoxy((now->x + 1) * 2, now->y + 1);
	printf("♀");  //输出起点;

	gotoxy(1, end->x + 3);
	printf("direction:↑\t↓\t←\t→\n help: F1\n quit: ESC\n");
	gotoxy(1, end->x + 6); //隐藏光标

	while (now->x != n - 2 || now->y != n - 2)//当没有到达终点时
	{
		if (GetAsyncKeyState(VK_UP))//四个if判断是否有方向键输入
		{
			if (maze[now->x - 1][now->y] == 0)
			{
				gotoxy((now->y + 1) * 2, now->x + 1 - 1);
				printf("♀");
				gotoxy((now->y + 1) * 2, now->x + 1);
				printf("  ");
				now->x--;
				gotoxy(0, end->x + 6);
				Sleep(100);
			}
		}
		else if (GetAsyncKeyState(VK_DOWN))
		{
			if (maze[now->x + 1][now->y] == 0)//下边可以走,则相应位置输出小人,现在位置输出空格
			{
				gotoxy((now->y + 1) * 2, now->x + 1 + 1); //上边的x加一是变化行所以这里对应的列加以一;单加一只是不变,再加一才是加一
				printf("♀");
				gotoxy((now->y + 1) * 2, now->x + 1);   //横坐标的变化要俩倍是因为涉及非英文字符的输出迷宫
				printf("  ");
				now->x++;
				gotoxy(0, end->x + 6);
				Sleep(100);
			}
		}
		else if (GetAsyncKeyState(VK_LEFT))
		{
			if (maze[now->x][now->y - 1] == 0)
			{
				gotoxy((now->y + 1) * 2 - 2, now->x + 1);
				printf("♀");
				gotoxy((now->y + 1) * 2, now->x + 1);
				printf("  ");
				now->y--;
				gotoxy(0 , end->x + 6);
				Sleep(100);
			}
		}
		else if (GetAsyncKeyState(VK_RIGHT))
		{
			if (maze[now->x][now->y + 1] == 0)
			{
				gotoxy((now->y + 1) * 2 + 2, now->x + 1);
				printf("♀");
				gotoxy((now->y + 1) * 2, now->x + 1);
				printf("  ");
				now->y++;
				gotoxy(0, end->x + 6);
				Sleep(100);
			}
		}

		else if (GetAsyncKeyState(VK_F1))
		{
			system("cls");
			return OK;
		}
		else if (GetAsyncKeyState(VK_ESCAPE))
		{
			system("cls");
			printf("COME ON!\n");
			return OK;
		}

	}
	printf("\n\n\n\t\t\tLOVE is so beauty!\n\n\t\t\t");
	return OK;
}
void gotoxy(int x, int y)
{
	COORD pos = { x, y };
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hOut, pos);
}
/*********************************迷宫主函数***********************************/
int lovemaze()
{
	printf("design by sailor_luo!\n2015\\12\\21\n");
	system("pause");
	system("cls");

	HANDLE color;
	color = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(color, FOREGROUND_GREEN);

	Pos start, end;
	start = (Pos)malloc(sizeof(Pos));
	end = (Pos)malloc(sizeof(Pos));
	static int **p;

	printf("请输入您的选择:\n");
	printf("◇═══════════════════════════════◇\n");
	printf("◇                        MAZE    MENU                          ◇\n");
	printf("◇═══════════════════════════════◇\n");
	printf("◇--------     1:game         ****          2:visit    ---------◇\n");
	printf("◇═══════════════════════════════◇\n");
	int c = 0;
	scanf_s("%d", &c);

PRI:
	printf("plsese input the size of this maze you want:\t");
	scanf_s("%d", &n);                        //how many lines of this maze

	if (n < 5)
	{
		system("cls");
		printf("It's too small!\n");
		goto PRI;
	}
	else if (n % 2 == 0)
	{
		system("cls");
		printf("please input odd!\n");
		goto PRI;
	}
	else if (n > 35)
	{
		printf("It's too hard! are you sure? 1:yes 2:no\t");
		int a = 0;
		scanf_s("%d", &a);
		while (a != 1)
			goto PRI;
	}
	else if (n < 15)
	{
		printf("It's too easy! are you sure? 1:yes 2:no\t");
		int a = 0;
		scanf_s("%d", &a);
		while (a != 1)
			goto PRI;
	}

	p = (int **)malloc(sizeof(int *)* n);
	for (i = 0; i < n; i++)
		p[i] = (int *)malloc(sizeof(int)* n); //get the momery of the array

	make_maze(p, n);                            //make this erray

	end->x = end->y = n - 2; //设置入口和出口
	start->y = start->x = 1;

	switch (c) //选择功能,是走迷宫游戏还是看迷宫生成
	{
	case 1: Game(p, n);
		if (GetAsyncKeyState(VK_F1))
		{
			Maze_Path(p, n, start, end);
			print_maze(p, n);
			system("pause"); return OK;
		}
		else
			system("pause"); return OK;
	case 2:print_maze(p, n); break;                           //output the maze you make
	default: printf("don't do this!\n");
	}
	if (Maze_Path(p, n, start, end) == ERROR)
		printf("\nThis maze haven't path!\n");
	else
	{
		printf("\nThe maze has the path to end!\nDo you want to get the path?\n1: yes 2: no\t");
		int a;
		scanf_s("%d", &a);
		switch (a)
		{
		case 1: system("cls"); print_maze(p, n); break;
		case 2: break;
		}
	}

	system("pause");
	return 0;
}

运行结果如下:



平心静气,努力向前

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值