经典游戏问题算法集
<P><FONT color=#ff0000>1.奇数阶魔方阵</FONT><br> #include <stdio.h><br>#include <stdlib.h></P><P>#define MAXSIZE 20</P>
<P>void main(void)<br>{<br> int matrix[MAXSIZE][MAXSIZE]; /* the magic square */<br> int count; /* 1..n*n counting */<br> int row; /* row index */<br> int column; /* column index */<br> int order; /* input order */<br> char line[100];</P>
<P> printf("\nOdd Order Magic Square Generator");<br> printf("\n================================");<br> printf("\n\nOrder Please --> ");<br> gets(line);<br> order = atoi(line);</P>
<P> if (order > MAXSIZE)<br> printf("\n*** ERROR *** Order should be <= %d", MAXSIZE);<br> else if (order % 2 == 0)<br> printf("\n*** ERROR *** Order must be an odd integer");<br> else {<br> row = 0; /* start of from the middle */<br> column = order/2; /* of the first row. */<br> for (count = 1; count <= order*order; count++) {<br> matrix[row][column] = count; /* put next # */<br> if (count % order == 0) /* move down ? */<br> row++; /* YES, move down one row */<br> else { /* compute next indices */<br> row = (row == 0) ? order - 1 : row - 1;<br> column = (column == order-1) ? 0 : column + 1;<br> }<br> }<br> printf("\n\nMagic Square of order %d :\n\n", order);<br> for (row = 0; row < order; row++) {<br> for (column = 0; column < order; column++)<br> printf("%4d", matrix[row][column]);<br> printf("\n");<br> }<br> }<br>}<br><FONT color=#ff0000>-------------------------------------------------------------------------------------------------------------------------------------------</FONT><br><FONT color=#ff3300>2.单偶数阶魔方阵</FONT><br>#define MAXSIZE 30</P>
<P>void singly_even(int [][MAXSIZE], int);<br>void magic_o(int [][MAXSIZE], int);<br>void exchange(int [][MAXSIZE], int);</P>
<P>/* ------------------------------------------------------ */<br>/* FUNCTION singly_even : */<br>/* This is the driver program. It fills the upper-left*/<br>/* lower-right, upper-right and lower-left parts by using */<br>/* odd order magic square routine. Then exchange some */<br>/* parts in each routine in order to maintain the magic */<br>/* properties. */<br>/* ------------------------------------------------------ */</P>
<P>void singly_even(int matrix[][MAXSIZE], int n)<br>{<br> int half = n/2;</P>
<P> magic_o(matrix, half);<br> exchange(matrix, n);<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION magic_o : */<br>/* Odd order magic square routine. It fills the block */<br>/* bounded by left, right, top and bottom with numbers */<br>/* starting from 'start'. Otherwise all are the same as */<br>/* the magic square routine discussed before. */<br>/* ------------------------------------------------------ */</P>
<P>void magic_o(int matrix[][MAXSIZE], int n)<br>{<br> int count; /* fill counting */<br> int row; /* row index */<br> int column; /* column index */</P>
<P> row = 0; /* start of from the middle */<br> column = n/2; /* of the first row. */<br> for (count = 1; count <= n*n; count++) {<br> matrix[row][column] = count; /* put # in A */<br> matrix[row+n][column+n] = count + n*n; /* in B */<br> matrix[row][column+n] = count + 2*n*n; /* in C */<br> matrix[row+n][column] = count + 3*n*n; /* in D */<br> if (count % n == 0) /* move downward ? */<br> row++; /* YES, move down one row */<br> else { /* compute next indices */<br> row = (row == 0) ? n - 1 : row - 1;<br> column = (column == n-1) ? 0 : column + 1;<br> }<br> }<br>}</P>
<P>#define SWAP(x,y) { int t; t = x; x = y; y = t;}</P>
<P>void exchange(int x[][MAXSIZE], int n)<br>{<br> int width = n / 4;<br> int width1 = width - 1;<br> int i, j;</P>
<P> for (i = 0; i < n/2; i++)<br> if (i != width) { /* if not the width-row */<br> for (j = 0; j < width; j++) <br> SWAP(x[i][j], x[n/2+i][j]);<br> for (j = 0; j < width1; j++)<br> SWAP(x[i][n-1-j], x[n/2+i][n-1-j]);<br> }<br> else { /* width-row is special */<br> for (j = 1; j <= width; j++)<br> SWAP(x[width][j], x[n/2+width][j]);<br> for (j = 0; j < width1; j++)<br> SWAP(x[width][n-1-j], x[n/2+width][n-1-j]);<br> }<br>}</P>
<P>/* ------------------------------------------------------ */</P>
<P>#include <stdio.h><br>#include <stdlib.h></P>
<P>void main(void)<br>{<br> int matrix[MAXSIZE][MAXSIZE];<br> int n;<br> int i, j;<br> char line[100];</P>
<P> printf("\nSingly-Even Order Magic Square");<br> printf("\n==============================");<br> printf("\n\nOrder Please (must be 2*(2k+1)) --> ");<br> gets(line);<br> n = atoi(line);</P>
<P> if (n % 2 == 0 && (n/2) % 2 == 1) {<br> singly_even(matrix, n);<br> printf("\n");<br> for (i = 0; i < n; i++) {<br> for (j = 0; j < n; j++)<br> printf("%4d", matrix[i][j]);<br> printf("\n");<br> }<br> }<br> else<br> printf("\n*** Illegal Order ***");<br>}<br><FONT color=#ff3300>--------------------------------------------------------------------------------------------------------------------------------------------------<br>3.双偶数阶魔方阵<br></FONT>#include <stdio.h><br>#include <stdlib.h></P>
<P>#define MAXSIZE 20 /* square size */<br>#define MARK -1 /* marker for build up */</P>
<P>void main(void)<br>{<br> int square[MAXSIZE][MAXSIZE]; /* the square */<br> int n; /* order of the magic square*/<br> int count, inv_count; /* 1 -> n^2 and n^2 -> 1 */<br> int marker; /* working marker 1,-1,1,-1 */<br> int i, j;<br> char line[100];</P>
<P> printf("\nDoubly-Even Magic Square");<br> printf("\n========================");<br> printf("\n\nOrder (4*m, m>0) please --> ");<br> gets(line);<br> n = atoi(line);<br> if (n % 4 != 0)<br> printf("\n*** Illegal Order *****");<br> else {<br> marker = MARK; /* mark the upper part */<br> for (i = 0; i < n/2; i++, marker = -marker)<br> for (j = 0; j < n/2; j++, marker = -marker)<br> square[i][j] = square[i][n-1-j] = marker;</P>
<P> count = 1; /* upward counter */<br> inv_count = n*n; /* downward counter */<br> for (i = 0; i < n/2; i++)<br> for (j = 0; j < n; j++)<br> if (square[i][j] != MARK) { /* marked*/<br> square[i][j] = count++;<br> square[n-1-i][n-1-j] = inv_count--;<br> }<br> else { /* unmarked */<br> square[i][j] = inv_count--;<br> square[n-1-i][n-1-j] = count++;<br> }<br> printf("\n");<br> for (i = 0; i < n; i++) {<br> for (j = 0; j < n; j++)<br> printf("%4d", square[i][j]);<br> printf("\n");<br> }<br> }<br>}<br>----------------------------------------------------------------------------------------------------------------------------------------------------<br><br></P>
[align=right][color=#000066][此贴子已经被作者于2006-3-29 18:06:09编辑过][/color][/align]
<P><FONT color=#ff0000>4.八皇后问题公式解</FONT><br>#include <stdio.h><br>#include <stdlib.h></P>
<P>#define MAXSIZE 30<br>#define MARK 'Q'</P>
<P>void initial(void);<br>void display(void);<br>void class_1(void);<br>void class_2(void);<br>void class_3(void);<br>void class_4(void);</P>
<P>int n; /* input board size */<br>char board[MAXSIZE+1][MAXSIZE+1]; /* the chess board */</P>
<P>void main(void)<br>{<br> void (*funct[])() = { class_1, class_2, /* functions */<br> class_4, class_3, /* of four */<br> class_1, class_2 /* classes */<br> };<br> char line[100];</P>
<P> printf("\nOne Solution for N Queens' Problem");<br> printf("\n==================================");<br> printf("\n\nBoard Size Please (N > 3) --> ");<br> gets(line);<br> n = atoi(line);</P>
<P> if (n > 3) {<br> initial(); /* initial the chess board */<br> (*funct[n % 6])(); /* call appropriate funct. */<br> display(); /* print result */<br> }<br> else<br> printf("\nIllegal Board Size.");<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION initial : */<br>/* Initialize the chess board to blank. */<br>/* ------------------------------------------------------ */</P>
<P>void initial(void)<br>{<br> int i, j;</P>
<P> for (i = 1; i <= n; i++)<br> for (j = 1; j <= n; j++)<br> board[i][j] = ' ';<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION display : */<br>/* Function to display the chess board. */<br>/* ------------------------------------------------------ */</P>
<P>#define DRAWGRID(N) { int i; \<br> printf("\n+"); \<br> for (i = 1; i <= N; i++) \<br> printf("-+"); \<br> }</P>
<P><br>#define DRAWLINE(N, r) { int i; \<br> printf("\n|"); \<br> for (i = 1; i <= N; i++) \<br> printf("%c|", board[r][i]);\<br> }</P>
<P>void display(void)<br>{<br> int r;</P>
<P> DRAWGRID(n);<br> for (r = 1; r <= n; r++) {<br> DRAWLINE(n, r);<br> DRAWGRID(n);<br> }<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION class_1 : */<br>/* Solution for n mod 6 == 0 or 4. */<br>/* ------------------------------------------------------ */</P>
<P>void class_1(void)<br>{<br> int i;</P>
<P> for (i = 1; i <= n/2; i++)<br> board[2*i][i] = board[2*i-1][n/2+i] = MARK;<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION class_2 : */<br>/* Solution for n mod 6 == 1 or 5. */<br>/* ------------------------------------------------------ */</P>
<P>void class_2(void)<br>{<br> int i;</P>
<P> for (i = 1; i <= (n-1)/2; i++)<br> board[2*i][i] = MARK;<br> for (i = 1; i <= (n+1)/2; i++)<br> board[2*i-1][(n-1)/2+i] = MARK;<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION class_3 : */<br>/* Solution for n mod 6 == 3. */<br>/* ------------------------------------------------------ */</P>
<P>void class_3(void)<br>{<br> int i;</P>
<P> for (i = 1; i <= (n-3)/2; i++)<br> board[2*i+2][i] = board[2*i+3][(n-1)/2+i] = MARK;<br> board[1][n-1] = board[2][(n-2)/2] = board[3][n] = MARK;<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION class_4 : */<br>/* Solution for n mod 6 = 2. */<br>/* ------------------------------------------------------ */</P>
<P>void class_4(void)<br>{<br> int i;</P>
<P> if (n > 8) {<br> for (i = 1; i <= 3; i++)<br> board[2*i-1][n/2-2+i] = MARK;<br> board[2][n] = board[4][1] = board[6][n-1] = MARK;<br> for (i = 1; i <= n/2 - 3; i++)<br> board[2*i+5][i+1] = board[2*i+6][n/2+1+i] = MARK;<br> }<br> else {<br> for (i = 1; i <= 4; i++)<br> board[2*i][i] = MARK;<br> board[1][6] = board[3][5] = MARK;<br> board[5][8] = board[7][7] = MARK;<br> }<br>}<br></P>
[align=right][color=#000066][此贴子已经被作者于2006-3-29 18:06:52编辑过][/color][/align]
<P><FONT color=#ff3300>5.八皇后问题递归解</FONT><br>#include <stdio.h><br>#include <stdlib.h></P>
<P>#define MAXSIZE 20 /* max. board size */<br>#define DIAG_SIZE 39 /* max. # of diagonals */<br>#define OCCUPIED 0 <br>#define EMPTY 1</P>
<P>void initial(void);<br>void display(void);<br>void try(int);</P>
<P>int pos[MAXSIZE+1]; /* pos[j]=i means Q is (i,j)*/<br>int in_row[MAXSIZE+1]; /* in_row[i] true->row occ. */<br>int diag[DIAG_SIZE+1]; /* diag[i] or back_diag[i] */<br>int back_diag[DIAG_SIZE+1]; /* = true -> occupied. */<br>int n; /* input board size */<br>int count = 0; /* # of solutions counter */</P>
<P>void main(void)<br>{<br> int i, j;<br> char line[100];</P>
<P> printf("\nAll Possible Solutions of N Queens' Problem");<br> printf("\n===========================================");<br> printf("\n\nBoard Size (N > 3) --> ");<br> gets(line);<br> n = atoi(line);</P>
<P> initial();<br> try(1); /* starting from column 1 */<br> printf("\n\nThere are %d solutions in total.", count);<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION initial : */<br>/* Function to initial the chess board. */<br>/* ------------------------------------------------------ */</P>
<P>void initial(void)<br>{<br> int i;</P>
<P> for (i = 1; i <= n; i++)<br> in_row[i] = EMPTY;<br> for (i = 1; i <= 2*n - 1; i++)<br> diag[i] = back_diag[i] = EMPTY;</P>
<P> printf("\nSolutions are represented the row # in a column");<br> printf("\n\n #");<br> for (i = 1; i <= n; i++)<br> printf("%3d", i);<br> printf("\n---");<br> for (i = 1; i <= n; i++)<br> printf(" --");<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION display : */<br>/* Function to display a single solution. */<br>/* ------------------------------------------------------ */</P>
<P>void display(void)<br>{<br> int i;</P>
<P> printf("\n%3d", count);<br> for (i = 1; i <= n; i++)<br> printf("%3d", pos[i]);<br>}</P>
<P><br>/* ------------------------------------------------------ */<br>/* FUNCTION try : */<br>/* Given a column number, this function tries to put */<br>/* a queen on some row of that column until all possible */<br>/* rows are attampted. */<br>/* ------------------------------------------------------ */</P>
<P>#define SAVE(r,c) (in_row[r] && back_diag[r+c-1] && diag[n-(c-r)])<br>#define SET(r,c) { pos[c] = r; \<br> in_row[r] = OCCUPIED; \<br> back_diag[r+c-1] = OCCUPIED; \<br> diag[n-(c-r)] = OCCUPIED; \<br> }<br>#define RESET(r,c) { in_row[r] = EMPTY; \<br> back_diag[r+c-1] = EMPTY; \<br> diag[n-(c-r)] = EMPTY; \<br> }<br><br>void try(int column)<br>{<br> int row;</P>
<P> for (row = 1; row <= n; row++) /* for each row */<br> if (SAVE(row, column)) { /* is it save ? */<br> SET(row, column); /* YES, make a record*/<br> if (column < n) /* all columns tried?*/<br> try(column+1); /* NO, try next col. */<br> else {<br> count++; /* OR, we found a sol*/<br> display(); /* display it. */<br> }<br> RESET(row, column); /* restore and back. */<br> }<br>}<br></P>
[align=right][color=#000066][此贴子已经被作者于2006-3-29 18:08:17编辑过][/color][/align]
<P><FONT color=#ff0000>6.武士巡逻问题</FONT></P>
<P>#include <stdio.h><BR>#include <stdlib.h></P>
<P>#define MAXSIZE 10 /* max. board size */<BR>#define MAX_STACK 100 /* stack size = board-size^2*/<BR>#define SUCCESS 1 /* return value for a succ. */<BR>#define FAILURE 0 /* for a failure. */<BR>#define EMPTY -1 /* value to indicate empty */</P>
<P>/* ----------------- external variables ----------------- */</P>
<P>int board[MAXSIZE+1][MAXSIZE+1]; /* chess board */<BR>int n; /* working board size */<BR>int offset_x[] = { 2, 1, -1, -2, -2, -1, 1, 2};<BR>int offset_y[] = { 1, 2, 2, 1, -1, -2, -2, -1};</P>
<P>int path_x[MAX_STACK+1]; /* stack for x coordinate */<BR>int path_y[MAX_STACK+1]; /* stack for y coordinate */<BR>int direction[MAX_STACK+1]; /* stack for direction */<BR>int top; /* stack pointer */</P>
<P>/* ----------------- function prototype ----------------- */</P>
<P>void initial(void);<BR>void display(void);<BR>int try(int, int);</P>
<P>/* -------------------- main program -------------------- */</P>
<P>void main(void)<BR>{<BR> int row, column;<BR> char line[100];</P>
<P> printf("\nRecursive Knight Tour Problem");<BR> printf("\n=============================");<BR> printf("\n\nBoard Size ----> ");<BR> gets(line);<BR> n = atoi(line);<BR> printf( "Start Row -----> ");<BR> gets(line);<BR> row = atoi(line);<BR> printf( "Start Column --> ");<BR> gets(line);<BR> column = atoi(line);<BR> <BR> initial();<BR> if (try(row, column) == FAILURE)<BR> printf("\nNO SOLUTION AT ALL.");<BR> else<BR> display();<BR>}</P>
<P><BR>/* ------------------------------------------------------ */<BR>/* FUNCTION initial : */<BR>/* initialize the chess board to EMPTY. */<BR>/* ------------------------------------------------------ */</P>
<P>void initial(void)<BR>{<BR> int i, j;</P>
<P> for (i = 1; i <= n; i++)<BR> for (j = 1; j <= n; j++)<BR> board[i][j] = EMPTY;<BR>}</P>
<P><BR>/* ------------------------------------------------------ */<BR>/* FUNCTION display : */<BR>/* display to chess board. */<BR>/* ------------------------------------------------------ */</P>
<P>#define DRAWGRID(N) { int i; \<BR> printf("\n+"); \<BR> for (i = 1; i <= N; i++) \<BR> printf("--+"); \<BR> }</P>
<P><BR>#define DRAWLINE(N, r) { int i; \<BR> printf("\n|"); \<BR> for (i = 1; i <= N; i++) \<BR> printf("%2d|",board[r][i]);\<BR> }</P>
<P><BR>void display(void)<BR>{<BR> int r;</P>
<P> printf("\n\nHere is One Possible Solution :\n");<BR> DRAWGRID(n);<BR> for (r = 1; r <= n; r++) {<BR> DRAWLINE(n,r);<BR> DRAWGRID(n);<BR> }<BR>}</P>
<P><BR>/* ------------------------------------------------------ */<BR>/* FUNCTION try : */<BR>/* The main non-recursive backtrack working routine. */<BR>/* ------------------------------------------------------ */</P>
<P>#define YES 1<BR>#define NO 0<BR>#define BOARD(x,y) (1<=x) && (x<=n) && (1<=y) && (y<=n)<BR>#define CHECK(x,y) board[x][y] == EMPTY<BR>#define PUSH(x,y) { top++; \<BR> path_x[top] = x; path_y[top] = y; \<BR> direction[top] = 0; \<BR> board[x][y] = top; \<BR> }</P>
<P>int try(int x, int y)<BR>{<BR> int new_x, new_y;<BR> int found;</P>
<P> top = -1; /* initial to empty */<BR> PUSH(x, y); /* push first pos. and dir. */<BR> while (top < n*n-1) { /* loop until the board full*/<BR> found = NO; <BR> while (direction[top] < 8) { /* try all 8 pos. */<BR> new_x = path_x[top] + offset_x[direction[top]];<BR> new_y = path_y[top] + offset_y[direction[top]];<BR> if (BOARD(new_x,new_y) && CHECK(new_x,new_y)) {<BR> PUSH(new_x, new_y); /* a new pos. PUSH*/<BR> found = YES; /* set flag */<BR> break; /* try next pos. */<BR> }<BR> else<BR> direction[top]++; /* OR try next dir*/<BR> }<BR> if (!found) /* if no new pos. is found */<BR> if (top > 0) { /* do we have prev. item? */<BR> board[path_x[top]][path_y[top]] = EMPTY;<BR> direction[--top]++; /* YES, backtrack */<BR> }<BR> else<BR> return FAILURE; /* otherwise, FAILURE */<BR> }<BR> return SUCCESS; /* all pos. visited. DONE */<BR>}<BR></P> <P><FONT color=#ff0000>7.环游世界问题</FONT></P>
<P>#include <stdio.h></P>
<P>#define MAXSIZE 30 /* no more than 30 vertices */<BR>#define ALWAYS 1<BR>#define SUCCESS 1<BR>#define FAILURE 0<BR>#define YES 1<BR>#define NO 0</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION read_in : */<BR>/* Read in the number of vertices and the edges. Then */<BR>/* build up the adjacenct matrix. NOTE that because the */<BR>/* graph is undirected, an edga (s,t) will represent two */<BR>/* 'edges' in the graph, namely (s,t) and (t,s). This */<BR>/* function reflects this fact by set two entries. */<BR>/* ------------------------------------------------------ */</P>
<P>void read_in(int connected[][MAXSIZE], int *n)<BR>{<BR> int i, j;</P>
<P> scanf("%d", n); /* read in the number of VTX*/<BR> for (i = 0; i < *n; i++) /* clear the adjacent matrix*/<BR> for (j = 0; j < *n; j++)<BR> connected[i][j] = NO;</P>
<P> scanf("%d%d", &i, &j); /* read in first edge */<BR> while (i != 0 && j != 0) { /* end ? */<BR> connected[i-1][j-1] = YES; /* NO, setup two */<BR> connected[j-1][i-1] = YES; /* symmetric edges */<BR> scanf("%d%d", &i, &j); /* read next one */<BR> }<BR> for (i = 0; i < *n; i++) /* clear diagonal */<BR> connected[i][i] = NO;<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION hamilton : */<BR>/* Given the adjacent matrix connected[], the number */<BR>/* of vertices and the start vertex, this function finds */<BR>/* a Hamilton Cycle and stores it in cycle[]. */<BR>/* ------------------------------------------------------ */</P>
<P>int hamilton(int connected[][MAXSIZE], int cycle[], int n, int start)<BR>{<BR> int *visited; /* visited marks */<BR> int top, i;</P>
<P> visited = (int *) malloc(sizeof(int)*n); /* get mem. */<BR> for (i = 0; i < n; i++) /* clear marks to NO */<BR> visited[i] = NO;<BR> visited[start] = YES; /* but the start has visited*/</P>
<P> cycle[0] = start; /* the cycle has 'start' */<BR> cycle[1] = 0; /* next in cycle is VTX 0 */<BR> top = 1; /* the top working element */</P>
<P> while (ALWAYS) { /* loop until done */<BR> for (i = cycle[top]; i < n; i++) /* find next */<BR> if (connected[cycle[top-1]][i] && !visited[i])<BR> break;<BR> if (i < n) { /* all neighbors tried? */<BR> cycle[top] = i;/* NO, a new vertex in cycle*/<BR> visited[cycle[top]] = YES;<BR> if (top == n-1 && connected[cycle[top]][start]) {<BR> free(visited); /* if all visited ... */<BR> return SUCCESS;/* return SUCCES */<BR> }<BR> else /* otherwise, advance. */<BR> cycle[++top] = 0;<BR> }<BR> else { /* next not found ..... */<BR> visited[cycle[--top]] = NO; /* backtrack */<BR> if (top == 0) { /* return to the start VTX?*/<BR> free(visited); /* YES, failed. */<BR> return FAILURE;<BR> }<BR> cycle[top]++; /* NO, move to neighbr */<BR> }<BR> }<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION display : */<BR>/* Display the found cycle. */<BR>/* ------------------------------------------------------ */</P>
<P>void display(int cycle[], int n)<BR>{<BR> int i;<BR> <BR> printf("\n\nA Hamilton Cycle is Listed as Follows :");<BR> printf("\n\n%d", cycle[0]+1);<BR> for (i = 1; i < n; i++)<BR> printf("->%d", cycle[i]+1);<BR> printf("->%d", cycle[0]+1);<BR>}</P>
<P><BR>/* ------------------------------------------------------ */</P>
<P>void main(void)<BR>{<BR> int connected[MAXSIZE][MAXSIZE];<BR> int cycle[MAXSIZE];<BR> int n;</P>
<P> printf("\nHamilton Cycle Program");<BR> printf("\n======================");<BR> read_in(connected, &n);<BR> if (hamilton(connected, cycle, n, 0) == SUCCESS)<BR> display(cycle, n);<BR> else<BR> printf("\n\nNO Hamilton Cycle at all.");<BR>}<BR></P> <P><FONT color=#ff3300>8.一笔画问题</FONT><BR>#include <stdio.h><BR>#include <stdlib.h></P>
<P>#define MAXSIZE 20<BR>#define ALWAYS 1<BR>#define YES 1<BR>#define NO 0<BR>#define SUCCESS 1<BR>#define FAIL -1</P>
<P>/* ------------------------------------------------------ */<BR>/* types and external variables */<BR>/* ------------------------------------------------------ */</P>
<P>typedef struct node Node; /* trail node (linked list) */</P>
<P>struct node { /* a node consists of ... */<BR> int vertex; /* a vertex number field */<BR> Node *next; /* and a next node ptr */<BR>};</P>
<P>int connect[MAXSIZE][MAXSIZE]; /* the connection matrix */<BR>int deg[MAXSIZE]; /* degree array */<BR>int n; /* number of vertices */<BR>Node *trail; /* pointer to Euler trail */</P>
<P>/* ------------------------------------------------------ */<BR>/* function prototypes */<BR>/* ------------------------------------------------------ */</P>
<P>void read_in(void);<BR>Node *euler(void);<BR>int prepare(Node **, Node **);<BR>int find_next(Node **);<BR>void find_trail(int, Node **, Node **);<BR>void display(void);</P>
<P>/* ------------------------------------------------------ */</P>
<P>void main(void)<BR>{<BR> printf("\nEuler Trail Program");<BR> printf("\n===================\n");</P>
<P> read_in(); /* get data */<BR> trail = euler(); /* compute Euler Trail */<BR> display(); /* display result */<BR>}<BR> <BR>/* ------------------------------------------------------ */<BR>/* FUNCTION read_in : */<BR>/* This function reads in the connection matrix and */<BR>/* then compute the degree array. */<BR>/* ------------------------------------------------------ */</P>
<P>void read_in(void)<BR>{<BR> int i, j;<BR> char line[100];</P>
<P> gets(line); /* get in number of vertices*/<BR> n = atoi(line);<BR> for (i = 0; i < n; i++) { /* clear the connection mtx*/<BR> deg[i] = 0;<BR> for (j = 0; j < n; j++)<BR> connect[i][j] = 0;<BR> }<BR> gets(line); /* get 1st line of edge set */<BR> sscanf(line, "%d%d", &i, &j);<BR> while (i != 0 && j != 0) { /* end of file ? */<BR> if (i != j) { /* a loop ? */<BR> connect[i-1][j-1]++; /* increase edge cnt*/<BR> connect[j-1][i-1]++;<BR> deg[i-1]++; /* increase degree count */<BR> deg[j-1]++;<BR> }<BR> else /* ignore all self loops */<BR> printf("\n*** ERROR *** A loop found. Data ignored");<BR> gets(line); /* get next edge */<BR> sscanf(line, "%d%d", &i, &j);<BR> }<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION euler : */<BR>/* This is the main working routine of this program. */<BR>/* It calls prepare() to initialize various data field and*/<BR>/* some checks. Then compute the Euler Trail loop by loop*/<BR>/* ------------------------------------------------------ */</P>
<P>Node *euler(void)<BR>{<BR> Node *current; /* processing cursor */<BR> Node *head, *tail; /* bound a partial trail */<BR> Node *p1, *p2; /* working pointer variables*/<BR> int VTX;</P>
<P> if (prepare(&head, &tail) == FAIL) /* prepare data */<BR> return NULL; /* if fail, return NULL */</P>
<P> current = tail; /* start from the tail */<BR> while (ALWAYS) <BR> if ((VTX = find_next(&current)) != FAIL) {<BR> find_trail(VTX, &p1, &p2);<BR> p2->next = current->next; /* join the trail*/<BR> current->next = p1;<BR> current = p1; /* step to next node */<BR> }<BR> else<BR> break;<BR> return head; /* return the trail list */<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION prepare : */<BR>/* This function checks to see if there are more two */<BR>/* odd degree vertices. It reject a graph with more than */<BR>/* two odd degree vertices. Then it builds a preliminary */<BR>/* trail list consisting of one node (if all vertices are */<BR>/* even), or two nodes (for the two odd degree vertices). */<BR>/* ------------------------------------------------------ */</P>
<P>int prepare(Node **first, Node **last)<BR>{<BR> Node *p1, *p2;<BR> int no, odd_no, i;<BR> int odd[2];</P>
<P> for (no = odd_no = i = 0; i < n; i++) /* test odd deg*/<BR> if (deg[i] % 2 != 0) {<BR> odd_no++;<BR> if (no < 2)<BR> odd[no++] = i;<BR> }<BR> if (odd_no > 2) { /* more than two odd deg VTX*/<BR> printf("\n*** ERROR *** too many odd degree vertices.");<BR> return FAIL;<BR> }<BR> if (odd_no == 2) { /* exactly two odd VTX */<BR> p1 = (Node *) malloc(sizeof(Node)); /* get mem. */<BR> p2 = (Node *) malloc(sizeof(Node));<BR> connect[odd[0]][odd[1]]--; /* just remove this */<BR> connect[odd[1]][odd[0]]--; /* odd degree edge */<BR> deg[odd[0]]--;<BR> deg[odd[1]]--;<BR> p1->vertex = odd[0]; /* these two vertices are */<BR> p1->next = p2; /* the must for first step */<BR> p2->vertex = odd[1]; /* thus put them into the */<BR> p2->next = NULL; /* trail list */<BR> *first = p1; /* return this list */<BR> *last = p2;<BR> }<BR> else { /* all vertices are even */<BR> p1 = (Node *) malloc(sizeof(Node)); /* get mem. */<BR> p1->vertex = 0; /* it is the only one node */<BR> p1->next = NULL; /* in the trail list */<BR> *first = *last = p1;/* return the trail list */<BR> }<BR> return SUCCESS;<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION find_next : */<BR>/* Given a pointer to some vertex which has already */<BR>/* been put into trail list, this function scans the trail*/<BR>/* list in order to find a vertex with non-zero degree. */<BR>/* ------------------------------------------------------ */</P>
<P>int find_next(Node **p)<BR>{<BR> for (;(*p)!=NULL && deg[(*p)->vertex]==0; (*p)=(*p)->next)<BR> ;<BR> return ((*p) == NULL) ? FAIL : (*p)->vertex;<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION find_trail : */<BR>/* Given a vertex, this function computes a trail */<BR>/* starting from the given vertex and returns the trail */<BR>/* list found. */<BR>/* ------------------------------------------------------ */</P>
<P>void find_trail(int start, Node **head, Node **tail)<BR>{<BR> Node *first, *last, *ptr;<BR> int p, i, done;</P>
<P> first = last = NULL; /* no node in list currently*/<BR> p = start; /* p is a moving vertex */<BR> done = NO;<BR> while (ALWAYS) {<BR> for (i = 0; i < n && !connect[p][i]; i++)<BR> ; /* find a VTX adjacent to p */<BR> if (i < n) { /* p->i is possible */<BR> connect[p][i]--, connect[i][p]--; <BR> deg[p]--, deg[i]--;<BR> ptr = (Node *) malloc(sizeof(Node));<BR> ptr->vertex = i; /* make node and put */<BR> ptr->next = NULL; /* it into the trail */<BR> if (first == NULL)<BR> first = last = ptr;<BR> else {<BR> last->next = ptr;<BR> last = ptr;<BR> }<BR> p = i; /* step to the next */<BR> }<BR> else /* if can not proceed, stop */<BR> break;<BR> }<BR> *head = first; /* return the trail list */<BR> *tail = last;<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION display : */<BR>/* Simple routine. It display the Euler Trail. */<BR>/* ------------------------------------------------------ */</P>
<P>void display(void)<BR>{<BR> Node *ptr = trail;<BR> int i = 0;</P>
<P> if (trail == NULL) <BR> return;<BR> printf("\nAn Euler Trail has been Found :\n");<BR> for ( ; ptr->next != NULL; ptr = ptr->next, i++) {<BR> if (i % 15 == 0) printf("\n");<BR> printf("%2d->", ptr->vertex+1);<BR> }<BR> if (i % 15 == 0) printf("\n"); /* the last item */<BR> printf("%2d", ptr->vertex+1);<BR>}<BR></P> <P><FONT color=#ff0000>9.非递归河内之塔问题</FONT></P>
<P>#include <stdio.h><BR>#include <stdlib.h></P>
<P>#define MAX_DISK 31</P>
<P>int which_disk(unsigned long *);</P>
<P>void main(void)<BR>{<BR> int number_of_disk; /* the number of disks */<BR> int pin[MAX_DISK+1]; /* locations of disks */<BR> int dir[2]; /* directions; 0=pos,1=neg */<BR> int disk; /* disk to be moved */<BR> int next; /* next position of 'disk' */<BR> int index; /* direction subscript */<BR> unsigned long number_of_moves; /* number of moves */<BR> unsigned long counter; /* counter for Gray Code */<BR> unsigned long i; /* working */<BR> char line[100]; /* input line */</P>
<P> printf("\nIterative Towers of Hanoi Program");<BR> printf("\n=================================");<BR> printf("\n\nHow many disks (<=31) ? ");<BR> gets(line);</P>
<P> number_of_disk = atoi(line);<BR> number_of_moves = (0x01UL << number_of_disk) - 1;<BR> counter = 0; /* counter for Gray Code */</P>
<P> if (number_of_disk & 0x01) /* setup direction */<BR> dir[0] = 0, dir[1] = 1;<BR> else<BR> dir[0] = 1, dir[1] = 0;</P>
<P> for (i = 1; i <= number_of_disk; i++) /* set up loc. */<BR> pin[i] = 1;</P>
<P> printf("\n Step Disk # From To");<BR> printf("\n -----------------------------");</P>
<P> for (i = 1; i <= number_of_moves; i++) {<BR> disk = which_disk(&counter); /* get disk # */<BR> index = disk & 0x01; /* compute direction index*/<BR> next = (pin[disk] + dir[index]) % 3 + 1;<BR> printf("\n%6lu%8d%10d%8d", i, disk, pin[disk], next);<BR> pin[disk] = next;<BR> }<BR>}</P>
<P><BR>/* ------------------------------------------------------ */<BR>/* FUNCTION which_disk : */<BR>/* Given the previous counter value, this function */<BR>/* computes the only one bit changed from 0 to 1 by adding*/<BR>/* one. This value corresponding to Gray Code. */<BR>/* ------------------------------------------------------ */</P>
<P>int which_disk(unsigned long *counter)<BR>{<BR> unsigned long a, b, c;<BR> int i;</P>
<P> a = *counter;<BR> *counter = b = a + 1;<BR> for (c = a^b, i = 0; c != 0; c >>= 1, i++)<BR> ;<BR> return i;<BR>}<BR></P> <P><FONT color=#ff3300>10.生命游戏</FONT></P>
<P>#include <stdio.h><BR>#include <stdlib.h></P>
<P>#define MAXSIZE 50 /* board size */<BR>#define OCCUPIED 1 /* occupied flag */<BR>#define UNOCCUPIED 0<BR>#define YES 1<BR>#define NO 0</P>
<P>char cell[MAXSIZE][MAXSIZE]; /* the board */<BR>char workcopy[MAXSIZE][MAXSIZE]; /* a working copy */<BR>int row; /* No. of rows you want */<BR>int column; /* no. of columns you want */<BR>int generations; /* maximum no. of generation*/</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION read_in : */<BR>/* This function reads in the number of generations, */<BR>/* the number of rows, the number of columns and finally */<BR>/* the initial configuration (the generation 0). Then put*/<BR>/* your configuration to the center of the board. */<BR>/* ------------------------------------------------------ */</P>
<P>void read_in(void)<BR>{<BR> int max_row, max_col; /* max # of row and col. */<BR> int col_gap, row_gap; /* incremnet of row and col */<BR> int i, j;<BR> char line[100];</P>
<P> gets(line); /* read in gens, row and col*/<BR> sscanf(line, "%d%d%d", &generations, &row, &column);<BR> for (i = 0; i < row; i++)/* clear the board */<BR> for (j = 0; j < column; j++)<BR> cell[i][j] = UNOCCUPIED;<BR> max_col = 0; /* read in the config. */<BR> for (max_row = 0; gets(line) != NULL; max_row++) {<BR> for (i = 0; line[i] != '\0'; i++)<BR> if (line[i] != ' ')<BR> cell[max_row][i] = OCCUPIED;<BR> max_col = (max_col < i) ? i : max_col;<BR> }<BR> row_gap = (row - max_row)/2; /* the moving gap */<BR> col_gap = (column - max_col)/2;<BR> for (i = max_row + row_gap - 1; i >= row_gap; i--) {<BR> for (j = max_col + col_gap - 1; j >= col_gap; j--)<BR> cell[i][j] = cell[i-row_gap][j-col_gap];<BR> for ( ; j >= 0; j--)<BR> cell[i][j] = UNOCCUPIED;<BR> }<BR> for ( ; i >= 0; i--)<BR> for (j = 0; j < column; j++)<BR> cell[i][j] = UNOCCUPIED;<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION display : */<BR>/* Display the board. */<BR>/* ------------------------------------------------------ */</P>
<P>#define DRAW_BOARDER(n) { int i; \<BR> printf("\n+"); \<BR> for (i = 0; i < n; i++) \<BR> printf("-"); \<BR> printf("+"); \<BR> }<BR>void display(int gen_no)<BR>{<BR> int i, j;</P>
<P> if (gen_no == 0)<BR> printf("\n\nInitial Generation :\n");<BR> else<BR> printf("\n\nGeneration %d :\n", gen_no);</P>
<P> DRAW_BOARDER(column);<BR> for (i = 0; i < row; i++) {<BR> printf("\n|");<BR> for (j = 0; j < column; j++)<BR> printf("%c", (cell[i][j] == OCCUPIED) ? '*' : ' ');<BR> printf("|");<BR> }<BR> DRAW_BOARDER(column);<BR>}</P>
<P>/* ------------------------------------------------------ */<BR>/* FUNCTION game_of_life : */<BR>/* This is the main function of Game of Life. */<BR>/* ------------------------------------------------------ */</P>
<P>void game_of_life(void)<BR>{<BR> int stable; /* stable flag */<BR> int iter; /* iteration count */<BR> int top, bottom, left, right; /* neighborhood bound */<BR> int neighbors; /* # of neighbors */<BR> int cell_count; /* # of cells count */<BR> int done;<BR> int i, j, p, q;</P>
<P> display(0); /* display initial config. */<BR> done = NO;<BR> for (iter = 1; iter <= generations && !done; iter++) {<BR> memmove(workcopy, cell, MAXSIZE*MAXSIZE); /*copy*/<BR> stable = YES; /* assume it is in stable */<BR> cell_count = 0; /* # of survived cells = 0 */<BR> for (i = 0; i < row; i++) { /* scan each cell...*/<BR> top = (i == 0) ? 0 : i - 1;<BR> bottom = (i == row - 1) ? row-1 : i + 1;<BR> for (j = 0; j < column; j++) {<BR> left = (j == 0) ? 0 : j - 1;<BR> right = (j == column - 1) ? column-1 : j + 1;</P>
<P> /* compute number of neighbors */</P>
<P> neighbors = 0;<BR> for (p = top; p <= bottom; p++)<BR> for (q = left; q <= right; q++)<BR> neighbors += workcopy[p][q];<BR> neighbors -= workcopy[i][j];</P>
<P> /* determine life or dead */</P>
<P> if (workcopy[i][j] == OCCUPIED) <BR> if (neighbors == 2 || neighbors == 3) {<BR> cell[i][j] = OCCUPIED;<BR> cell_count++;<BR> }<BR> else<BR> cell[i][j] = UNOCCUPIED;<BR> else if (neighbors == 3) {<BR> cell[i][j] = OCCUPIED;<BR> cell_count++;<BR> }<BR> else<BR> cell[i][j] = UNOCCUPIED;<BR> stable = stable && (workcopy[i][j] == cell[i][j]);<BR> }<BR> }<BR> if (cell_count == 0) {<BR> printf("\n\nAll cells die out.");<BR> done = YES;<BR> }<BR> else if (stable) {<BR> printf("\n\nSystem enters a stable state.");<BR> done = YES;<BR> }<BR> else<BR> display(iter);<BR> }<BR>}</P>
<P>/* ------------------------------------------------------ */</P>
<P>void main(void)<BR>{<BR> read_in();<BR> game_of_life();<BR>}<BR></P> 强啊 [em14] 厉害..还看不懂..呵呵 [em17] 楼主好强啊,不过我们都看不懂[em03] 楼主的数据结构学得一定很好<BR>那几个算法都很难的,我看不懂,强啊! <P>请问一下atoi()是 什么意思?[em03]</P> 为什么用VC编译会出错??[em09] 有错自己可以调试<BR> 下次打包行不行啊!<BR> [em01]好劲啊! [em17]我靠,太强了<BR>
