<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Puzzle</title>
</head>

<body>

<blockquote>

<blockquote>
  <blockquote>

<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#FF0000" size="6"><b>Code  
Competition(4)&nbsp;</b></font>    
</p>
  </blockquote>
</blockquote>
</blockquote>
<div align="left">
  <pre><b><font color="#ff0000" size="5">A.First Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is actually first edition of <a href="CodingProb4.htm">Code Competition 4</a>. (Click to see the problem)</b></pre>
</div>
<div align="left">
  <pre><b>1¡£ Basic idea: </b></pre>
</div>
<div align="left">
  <pre><b>This is from last year of &quot;Code Competition&quot; of &quot;Concordia Computer Science Association&quot;(CCSS)</b></pre>
</div>
<div align="left">
  <pre><b>This is a quite unexpected difficult problem as I tried to use &quot;Breadth First Search&quot; which I never tried before.</b></pre>
</div>
<div align="left">
  <pre><b>I finished after more then one day! I guess I won't become the winning team as I think I am not the kind of </b></pre>
</div>
<div align="left">
  <pre><b>coding fast.</b></pre>
</div>
<div align="left">
<div align="left">
  <pre><b>Actually I tried <a href="Maze2.htm">&quot;Maze&quot; problem before</a> except that my old program cannot gurantee about &quot;shortest&quot; path. Even </b></pre>
</div>
<div align="left">
  <pre><b>in old program I add some kind of &quot;shortcut&quot;, still it is not a total solution. And I really want to try to use</b></pre>
</div>
<div align="left">
  <pre><b>&quot;Breadth First Search&quot;. However, it turned out quite complicated, even more complicated than &quot;Depth First Search&quot;.</b></pre>
</div>
<div align="left">
  <pre><b>At least I think so. I tried to find some algorithms in my &quot;Data Structure Bible&quot;. But they only give a very </b></pre>
</div>
<div align="left">
  <pre><b>common psudocode for graph which helps me little with this 3-son tree. After wasting almost a whole night usless</b></pre>
</div>
<div align="left">
  <pre><b>debating with &quot;MBA HU&quot; about &quot;Machine Authority&quot;, my time ran out like Mr. Sadam Hussain. And this morning I </b></pre>
</div>
<div align="left">
  <pre><b>tried my best to rewrote the way of &quot;searching next cousin&quot;. As soon as I hailed my success, I found out that </b></pre>
</div>
<div align="left">
  <pre><b>the problem even requires &quot;SEVERAL&quot; mazes to be input at one time! I fainted. I have to destroy all my tree and</b></pre>
</div>
<div align="left">
  <pre><b>output the result</b> <b>before I read next maze which means a &quot;Walk-Arround&quot; algorithms is required to delete all nodes.</b></pre>
</div>
<div align="left">
  <pre><b>It cost my noon sleep to finish tracing and debugging.</b></pre>
</div>
</div>
<div align="left">
  <pre><b>2¡£ Program design: </b></pre>
</div>
<div align="left">
  <pre><b>I design a &quot;huge&quot; struct to stand for our nodes. In order to prevent looping, I used the way similar to solution</b></pre>
</div>
<div align="left">
  <pre><b>that is to write a temporary &quot;*&quot; to represent every square I reached. In my old program, I actually record each</b></pre>
</div>
<div align="left">
  <pre><b>step in an array, and I check the contents to see if I am looping. Maybe that is more effiently, I really don't</b></pre>
</div>
<div align="left">
  <pre><b>know. As for find next sibling, I first try to find one of his uncle and then try to see if this uncle has any son</b></pre>
</div>
<div align="left">
  <pre><b>of which the level are same to my current node. Then this should be his &quot;cousin&quot;. If there is not a cousin for </b></pre>
</div>
<div align="left">
  <pre><b>this &quot;uncle&quot;, I try to find an &quot;uncle&quot; of this &quot;uncle&quot;, then try to find his child of same level of my node. And</b></pre>
</div>
<div align="left">
  <pre><b>so on, if there is no more uncle can be found, this means that there is no cousin. I have to find next generation</b></pre>
</div>
<div align="left">
  <pre><b>of my node by &quot;findFirstSon()&quot; function. Before output result, I erase the temporary mark &quot;*&quot;. &quot;Breadth First</b></pre>
</div>
<div align="left">
  <pre><b>Search&quot; will definitely give you the shortest path but it is not the shortest way to code.</b></pre>
</div>
<div align="left">
  <pre><b>3¡£ Major function£º</b></pre>
</div>
<div align="left">
  <pre><b>	A. void startSearch(Node* node)</b></pre>
</div>
<div align="left">
  <pre><b>	This function do the searching job, it tests each node to see if it is exit point. If not, it call addNode()</b></pre>
</div>
<div align="left">
  <pre><b>to add new children of this node. Then it tries to find next node to repeat by first try same generation, if</b></pre>
</div>
<div align="left">
  <pre><b>failed, try next generation.</b></pre>
</div>
<div style="WIDTH: 892px; HEIGHT: 102px" align="left">
  <pre><b>     </b><b>B. Node* nextSibling(Node* node)</b></pre>
  <pre>	This function find next node when constructing my tree. It first find &quot;same father brother&quot;, then try find next uncle,if</pre>
  <pre>the uncle has a same-level child, it return the child. If not, try the uncle of &quot;this uncle&quot; until no more uncle fits. It will</pre>
  <pre>try next generation.</pre>
  <pre><b>     C. Node* findSibling(Node* node)</b></pre>
  <pre>	This function does what I described above: first find an uncle to see if he has a same-level child. Until no more uncle can</pre>
  <pre>be found, it returns NULL to indicate this.</pre>
  <pre>	<b>D.  Node* findBrother(Node* node)</b></pre>
  <pre>	This is the function to find same-father brother: if you are left son, the next possible is mid son, or right son by sequence.</pre>
  <pre>If you are mid-son, the only possible is right son. if you are right son, you have no same-father brother.</pre>
  <pre>	<b>E. Node* findFirstSon(Node* node)</b></pre>
  <pre>	This is a &quot;level-defined&quot; searching for first possible child. Until you reach the level, you will repeat to find the </pre>
  <pre>first sequence child.</pre>
  <pre>	<b>F. Node* findUncle(Node* node)</b></pre>
  <pre>	It is simple, your uncle is one of your father's little brother. If you father doesnot have one, try your grandfather.</pre>
  <pre>	<b>G. void addNode(Node* node)</b></pre>
  <pre>	Node* doAdding(Node* node, Direction dir);</pre>
  <pre>	This function generate sons of this node with directions which means that according to the node's direction, you arrange</pre>
  <pre>the sequence of left, mid, right son accordingly. He has an internal function doAdding();</pre>
  <pre>	<b>H. bool solveMaze(FILE* stream)

	   void initialize();</b></pre>
  <pre>	Pls note the internal method initialize() which has to clear all nodes before we can re-construct the tree. However, this</pre>
  <pre>means a &quot;Walk-Arround&quot; from all leafs of tree to delete one by one. Its internal function &quot;findSingle()&quot; is similar as</pre>
  <pre>findFirstSon() except it doesnot require to go to certain depth levels.</pre>
  <pre><b>4¡£ Further improvement£º</b></pre>
  <pre><b>	A. I use too many recursive calls which may require too much memory.	</b></pre>
  <pre><b><font color="#FF0000"><i>	</i></font>B. I forgot to delete all tree when program ended.</b></pre>
  <pre>#include &lt;iostream&gt;
#include &lt;fstream&gt;</pre>
  <pre>using namespace std;</pre>
  <pre>enum Direction
{Up, Right, Down, Left};</pre>
  <pre>const Space = 32;</pre>
  <pre>const Wall = 'X';</pre>
  <pre>const Passed = '*';</pre>
  <pre>const Route = '.';</pre>
  <pre>const Return = '\n';</pre>
  <pre>const MaxRow = 20;</pre>
  <pre>const MaxCol = 70;</pre>
  <pre>const MaxStep = 200;</pre>
  <pre>char maze[MaxRow][MaxCol];</pre>
  <pre>struct Node
{
	Node* parent;
	Node* left;
	Node* mid;
	Node* right;
	int row;
	int col;
	Direction direction;
	int level;
};</pre>
  <pre>Node start;</pre>
  <pre>int level =0;</pre>
  <pre>int rowLimit = 0;</pre>
  <pre>int colLimit = 0;</pre>
  <pre>bool solveMaze(FILE* stream);</pre>
  <pre>bool inputFile(char* fileName);</pre>
  <pre>void outputFile(char* fileName);</pre>
  <pre>bool evalueNode(Node* node);</pre>
  <pre>void generateNode(Node* node);</pre>
  <pre>void startSearch(Node* node);</pre>
  <pre>Node* findSibling(Node* node);</pre>
  <pre>void recordPath(Node* node);</pre>
  <pre>Node* findUncle(Node* node);</pre>
  <pre>Node* findFirstSon(Node* node);</pre>
  <pre>Node* findBrother(Node* node);</pre>
  <pre>Node* nextNephew();</pre>
  <pre>void addPath(Node* node);
</pre>
  <pre>int main()
{
	FILE* f;
	f = fopen(&quot;c:\\nickinput.txt&quot;, &quot;r&quot;);
	while (solveMaze(f))
	{
		outputFile(&quot;c:\\nickoutput.txt&quot;);
	}
	return 0;
}</pre>
  <pre>void outputFile(char* fileName)
{
	FILE*  stream;
	stream = fopen(fileName, &quot;a&quot;);
	for (int i = 0; i&lt; rowLimit; i++)
	{
		for (int j =0; j &lt; colLimit; j++)
		{
			if (maze[i][j] == Passed)
			{
				maze[i][j] = Space;
			}
			fputc(maze[i][j], stream);
		}
		fputc('\n', stream);
	}
	fclose(stream);
}</pre>
  <pre>Node* findSingle(Node* node)
{
	Node* ptr= node;
	if (node != NULL)
	{
		ptr = findSingle(node-&gt;left);
		if (ptr==NULL)
		{
			ptr = findSingle(node-&gt;mid);
		}
		if (ptr==NULL)
		{
			ptr = findSingle(node-&gt;right);
		}
		if (ptr==NULL)
		{
			ptr = node;
		}
	}
	return ptr;
}</pre>
  <pre>void destroy(Node* ptr)
{
	if (ptr-&gt;parent-&gt;left == ptr)
	{
		ptr-&gt;parent-&gt;left = NULL;
	}
	if (ptr-&gt;parent-&gt;mid == ptr)
	{
		ptr-&gt;parent-&gt;mid = NULL;
	}
	if (ptr-&gt;parent-&gt;right == ptr)
	{
		ptr-&gt;parent-&gt;right = NULL;
	}
	delete ptr;
}
</pre>
  <pre>void initialize()
{
	Node* findSingle(Node* node);
	void destroy(Node* ptr);</pre>
  <pre>	Node* ptr = &amp;start;
	while (true)
	{
		ptr = &amp;start;
		ptr = findSingle(ptr);
		if (ptr!=&amp;start&amp;&amp;ptr!=NULL)
		{
			destroy(ptr);			
		}
		else
		{
			break;
		}
	}
	level =0;
	colLimit = 0;
	rowLimit = 0;
	start.row = 0;
	start.col = 0;
	start.left = NULL;
	start.mid  = NULL;
	start.right = NULL;
	start.parent = NULL;
	start.level = 0;
}



</pre>
  <pre>bool solveMaze(FILE* stream)
{
	void initialize();
	char ch;
	Node* ptr = &amp;start;
	bool setRoot = false;
	int i=0, j=0;
	</pre>
  <pre>	initialize();</pre>
  <pre>	ch = fgetc(stream);
	while(true)
	{
		j =0;
		while(ch!=Return)
		{
			maze[i][j] = ch;
			ch = fgetc(stream);
			j++;
		}
		i++;
		if (i ==1)
		{
			if (j==1)
			{
				return false;
			}
			colLimit = j;
		}
	</pre>
  <pre>		ch = fgetc(stream);
		if (ch==Return)
		{
			rowLimit = i;
			break;
		}
	</pre>
  <pre>		if (ch == Space&amp;&amp;!setRoot)
		{
			start.row = i;
			start.col = 0;
			setRoot = true;
			start.left = NULL;
			start.mid =NULL;
			start.right = NULL;
			start.parent = NULL;
			start.direction = Right;
			start.level = 0;
			maze[i][0] = Passed;
		}
	</pre>
  <pre>	}
	startSearch(ptr);
	return true;
	</pre>
  <pre>}</pre>
  <pre>Node* doAdding(Node* node, Direction dir)
{
	int row, col;
	Node* ptr;</pre>
  <pre>	row = node-&gt;row;
	col = node-&gt;col;</pre>
  <pre>	switch (dir)
	{
	case Up:
		row--;
		break;
	case Right:
		col++;
		break;
	case Down:
		row++;
		break;
	case Left:
		col--;
		break;
	}
	if (row&lt;0||row&gt;=rowLimit||col&lt;0||col&gt;=colLimit||maze[row][col]==Passed
		||maze[row][col]==Wall)
	{
		return NULL;
	}
	ptr = new Node;
	ptr-&gt;row = row;
	ptr-&gt;col = col;
	ptr-&gt;direction = dir;
	ptr-&gt;parent = node;
	ptr-&gt;left = NULL;
	ptr-&gt;mid = NULL;
	ptr-&gt;right = NULL;
	ptr-&gt;level = node-&gt;level + 1;
	maze[row][col] = Passed;
	return ptr;
}

</pre>
  <pre>void addNode(Node* node)
{
	Node* doAdding(Node* node, Direction dir);</pre>
  <pre>	maze[node-&gt;row][node-&gt;col] = Passed;
	switch (node-&gt;direction)
	{
	case Up:
		node-&gt;left = doAdding(node, Left);
		node-&gt;mid = doAdding(node, Up);
		node-&gt;right = doAdding(node, Right);
		break;
	case Right:
		node-&gt;left = doAdding(node, Up);
		node-&gt;mid = doAdding(node, Right);
		node-&gt;right = doAdding(node, Down);
		break;
	case Down:
		node-&gt;left = doAdding(node, Right);
		node-&gt;mid = doAdding(node, Down);
		node-&gt;right = doAdding(node, Left);
		break;
	case Left:
		node-&gt;left = doAdding(node, Down);
		node-&gt;mid = doAdding(node, Left);
		node-&gt;right = doAdding(node, Up);
		break;
	}
			</pre>
  <pre>}</pre>
  <pre>bool testNode(Node* node)
{
	if (node!=&amp;start&amp;&amp;node-&gt;col == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}</pre>
  <pre>Node* findUncle(Node* node)
{
	Node* ptr = node;
	if (ptr-&gt;parent!=NULL)
	{
		ptr = findBrother(ptr-&gt;parent);
		if (ptr!=NULL)
		{
			return ptr;
		}
		else
		{
			return findUncle(node-&gt;parent);
		}
	}
	return NULL;
}</pre>
  <pre>Node* findFirstSon(Node* node)
{
	Node* ptr = node;
	if (ptr==NULL)
	{
		return NULL;
	}
	if (ptr-&gt;level != level)
	{
		ptr = findFirstSon(node-&gt;left);
		if (ptr==NULL)
		{
			ptr = findFirstSon(node-&gt;mid);
		}
		if (ptr==NULL)
		{
			ptr = findFirstSon(node-&gt;right);
		}
		</pre>
  <pre>	}
	return ptr;
}</pre>
  <pre>Node* findBrother(Node* node)
{
	Node* ptr= NULL;
	if (node!= NULL)
	{
		if (node-&gt;parent==NULL)
		{
			return NULL;
		}</pre>
  <pre>		if (node-&gt;parent-&gt;left==node)
		{
			ptr = node-&gt;parent-&gt;mid;  //problem
			if (ptr==NULL)
			{
				ptr = node-&gt;parent-&gt;right;
			}
		}
		if (node-&gt;parent-&gt;mid == node)
		{
			ptr = node-&gt;parent-&gt;right;
		}
		return ptr;
	}
	return NULL;
}</pre>
  <pre>Node* findSibling(Node* node)
{
	Node* pUncle = node;
	Node* ptr;</pre>
  <pre>	while (true)
	{
		pUncle = findUncle(pUncle);
		if (pUncle ==NULL)
		{
			return NULL;
		}
		ptr = findFirstSon(pUncle);
		if (ptr!= NULL)
		{
			return ptr;
		}
	}	
}
</pre>
  <pre>Node* nextSibling(Node* node)
{
	Node* ptr = node;
	ptr = findBrother(node);
	if (ptr==NULL)
	{
		ptr = findSibling(node);
	}
	return ptr;
}</pre>
  <pre>	
Node* nextNephew()
{
	level++;
	return findFirstSon(&amp;start);
}</pre>
  <pre>void addPath(Node* node)
{
	maze[node-&gt;row][node-&gt;col] = Route;
	if (node-&gt;level == 0)
	{
		return;
	}
	else
	{
		addPath(node-&gt;parent);
	}
}
</pre>
  <pre>void startSearch(Node* node)
{
	Node* ptr;
	Node* pNode;
		</pre>
  <pre>	pNode = node;
	while (!testNode(pNode))
	{
		addNode(pNode);
		ptr = nextSibling(pNode);
		if (ptr==NULL)
		{
			ptr = nextNephew();
			if (ptr==NULL)
			{
				cout&lt;&lt;&quot;no solution!&quot;;
				//return;
			}
		}
		pNode = ptr;
	}</pre>
  <pre>	addPath(pNode);
}


</pre>
</div>
<p><font color="#0000FF">This is input file contents:</font>          


</p>

<pre><font color="#FF0000">XXXXXXXX
XX     X
   X XXX
XXX  X X
       X 
XXXXXXXX</font></pre>
<pre><font color="#FF0000">XXXXXXXXXX
X        X 
  XX XXXXX
XX       X
  XXXXXX X
X        X
XXXXXXXXXX</font></pre>
<pre><font color="#FF0000">X</font></pre>

<p><font color="#FF0000"><br>
</font>           


</p>

<p><font color="#0000FF">This is output file contents:</font>          


</p>

<pre><font color="#FF0000">XXXXXXXX
XX...  X
...X.XXX
XXX .X X
.....  X
XXXXXXXX
XXXXXXXXXX
X....    X
..XX.XXXXX
XX  .....X
..XXXXXX.X
X........X
XXXXXXXXXX</font></pre>

<p>¡¡          


</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                       
&nbsp;&nbsp;&nbsp; <a href="CodeCompetition3.htm">          







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="CodeCompetition1.htm"><img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</a>          


</p>

</body>

</html>
