目錄:
- 代碼:
- 分析:
- 匯編:
代碼:
main.c
#include <stdio.h>/*
程序描述:輸出N*N中符合左右對角線與上下左右方向都沒被使用的位置在每一行的所有情況使用檢測左上角,正上角,右上角 三個方向有沒有被使用來判斷該行該位置是否可以使用當檢測行大于N時,表示完成一種情況,按下回車鍵。從大于N行的這次find函數調用出棧。返回調用(使用大于N行的參數調用了find函數的)處。就是N行調用find函數的地方執行將N行原本選用好的位置重置,再找下一個。如果找到就重復上面大于N行的find函數調用如果沒找到,將調用N行的find函數出棧,返回到N-1行調用find函數的地方,在N-1行查找找到就再調用回N行,找不到就再出棧,返回上一行也就是調用處。總結:在本行找到就調用到下一行查找,本行找不到就返回到上一行查找,找到就再返回到下一行,找不到就再返回到上一行,實現將所有情況輸出*/
#define N 5typedef struct _tag_Pos
{int ios;int jos;
} Pos;static char board[N+2][N+2];//定義二維數組,加2用于上下左右四邊
static Pos pos[] = { {-1, -1}, {-1, 0}, {-1, 1} }; //定義用于向左上角,正上角,右上角的位置遞增的數組
static int count = 0;void init()//初始化數組函數
{int i = 0;int j = 0;for(i=0; i<N+2; i++)//將二維數組的四邊賦上'#'{board[0][i] = '#'; //上board[N+1][i] = '#'; //下board[i][0] = '#'; //左board[i][N+1] = '#'; //右}for(i=1; i<=N; i++)//將內部內容賦上空格{for(j=1; j<=N; j++){board[i][j] = ' ';}}
}void display()//將整個二維數組輸出顯示函數
{int i = 0;int j = 1;for(i=0; i<N+2; i++){for(j=0; j<N+2; j++){printf("%c", board[i][j]);}printf("\n");}
}int check(int i, int j)//檢測該位置是否符合要求
{int ret = 1;int p = 0;for(p=0; p<3; p++){int ni = i;int nj = j;while( ret && (board[ni][nj] != '#') )//判斷這個位置不是在四邊{ni = ni + pos[p].ios;nj = nj + pos[p].jos;//如果該位置的左上角方向有被使用了,不再進行的正上角與右上角的檢測//因為ret 為0了,如果第一個左上角位置沒有被使用。將一直位移比較//直至遇到'#'四邊ret = ret && (board[ni][nj] != '*');//判斷這個位置沒被使用}}return ret;
}void find(int i)//查找位置函數(主要函數)
{int j = 0;if( i > N ){count++;printf("Solution: %d\n", count);display();getchar();}else{for(j=1; j<=N; j++){if( check(i, j) ){board[i][j] = '*';find(i+1);//函數執行完出棧時將這個位置重置,相當在這一行重新找下一個符合要求的位置//在這一行找不到時,調用的這行的函數出棧。返回到上一行調用的這個位置//又將上一行的原來的使用的位置重置,找下一個符合要求的位置,如果找不到//就再返回上一行重設尋找,如果找到,就再調用自身從新到下一行找,//依此類推board[i][j] = ' ';}}}
}int main()
{init();find(1);return 0;
}
分析:
匯編: