home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-19 | 3.4 KB | 142 lines | [TEXT/CWIE] |
- /*
- Problem 03 - Perimeter
-
- You are in charge of protecting a set of defenseless homeowners from predators
- that roam the area by constructing a single fence of minimum length that
- encloses all of the homes.
-
- The prototype for your solution is as follows:
-
- typedef struct Node {
- long xCoord;
- long yCoord;
- } Node;
-
- void Perimiter(
- long numHomes,
- Node homesToEnclose[],
- long *numNodesInPerimiter,
- long nodesInPerimiter[]
- );
-
- You are given a list homesToEnclose of numHomes homes to protect (numbered 0
- to numHomes-1) by constructing a fence around the homes. You should return a
- list nodesInPerimiter of the numNodesInPerimiter homes to be connected by a
- fence. The fence must enclose all of the homes using the minimum amount of
- fencing material.
- */
-
- #include <MacTypes.h>
- #include <Math.h>
- #include "Solution.h"
-
- // Fill in your solution and then submit this folder
-
- // Team Name: Team Guiness
-
- #define FLOAT float
- #define PI 3.1415926535
- //-----------------------------------------
- static FLOAT FindRadian( FLOAT dx, FLOAT dy, FLOAT *d )
- {
- FLOAT result = 0;
-
- *d = dx*dx + dy*dy;
-
- if ( dx!=0 )
- {
- result = atanf( dy/dx );
- if ( dx < 0 )
- result = result+ PI;
- if ( dx > 0 && dy < 0 )
- result = result + 2 * PI;
- }
- else if ( dy > 0 )
- result = PI/2;
- else if ( dy < 0 )
- result = 1.5 * PI;
- else
- DebugStr("\pidentical nodes?");
- // result = atan2f( dy, dx );
-
- return result;
- }
- //------------------------------------
- static void TestRadian( void )
- {
- FLOAT stuff[] = { 10, 0, 0,
- 10, 10, PI/4,
- 0, 10, PI/2,
- -10, 10, .75 * PI,
- -10, 0, PI,
- -10, -10, 1.25 * PI,
- 0, -10, 1.5 * PI,
- 10, -10, 1.75 *PI };
- short i;
- FLOAT a,b, ignore;
-
- for (i=0;i<8;i++)
- {
- a = FindRadian( stuff[i*3], stuff[i*3+1], &ignore);
- b = stuff[i*3+2];
- }
- }
-
- //-----------------------------------------
- pascal void Perimeter(
- UInt32 numHomes,
- const Node homesToEnclose[],
- UInt32 *numNodesInPerimeter,
- UInt32 nodesInPerimeter[]
- )
- {
- Node *minNode, *thisNode,*curNode, *startNode;
- FLOAT *angles = (FLOAT*) NewPtr(sizeof(*angles) * numHomes);
- FLOAT lowRadian,curMinRadian;
- Boolean done = false;
- UInt32 i;
-
- TestRadian();
-
- *numNodesInPerimeter = 0;
- if (!angles) goto BAIL;
-
- minNode = thisNode = (Node*) homesToEnclose; // find min home in y, then x (if match)
- for (i=0;i<numHomes;i++,thisNode++)
- if (thisNode->yCoord < minNode->yCoord ||
- (thisNode->yCoord == minNode->yCoord && thisNode->xCoord < minNode->xCoord ))
- minNode = thisNode;
-
- curNode = startNode = minNode;
- lowRadian = 0;
- while (!done)
- {
- curMinRadian = 10.0; // something greater than 2 Pi
- for (i=0,thisNode = (Node*)homesToEnclose; i<numHomes;i++,thisNode++) // find node with minimal radian greater than last
- {
- FLOAT r;
- FLOAT minD = 100000000, thisD;
-
- if ( thisNode == curNode ) continue; // ignore the starting point
- r = FindRadian( thisNode->xCoord - curNode->xCoord,
- thisNode->yCoord - curNode->yCoord, &thisD );
- if ( r >= lowRadian )
- if ( r < curMinRadian || (r==curMinRadian && thisD < minD ) )
- {
- minD = thisD;
- minNode = thisNode;
- curMinRadian = r;
- }
- }
- UInt32 nodeIndex = minNode - (Node*)homesToEnclose;
- nodesInPerimeter[(*numNodesInPerimeter)++] = nodeIndex;
- curNode = minNode;
- lowRadian = curMinRadian; // save the last radian as the lower bounds for the next search
- if ( curNode == startNode )
- done=true;
- }
-
- BAIL:
- ;
- }
-