亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++算法設(shè)計之馬踏棋盤的實現(xiàn)

 更新時間:2022年02月15日 14:34:41   作者:蜜蜂采蜜  
這篇文章主要為大家詳細介紹了C++算法設(shè)計之馬踏棋盤的實現(xiàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了C++算法設(shè)計之馬踏棋盤的具體代碼,供大家參考,具體內(nèi)容如下

(一)馬踏棋盤經(jīng)典算法描述:

  (1)馬踏棋盤是經(jīng)典的程序設(shè)計問題之一,主要的解決方案有兩種:一種是基于深度優(yōu)先搜索的方法,另一種是基于貪婪算法的方法。第一種基于深度優(yōu)先搜索的方法是比較常用的算法,深度優(yōu)先搜索算法也是數(shù)據(jù)結(jié)構(gòu)中的經(jīng)典算法之一,主要是采用遞歸的思想,一級一級的尋找,遍歷出所有的結(jié)果,最后找到合適的解。而基于貪婪的算法則是制定貪心準則,一旦設(shè)定不能修改,他只關(guān)心局部最優(yōu)解,但不一定能得到最優(yōu)解。

【問題描述】關(guān)于馬踏棋盤的基本過程:國際象棋的棋盤為 8*8 的方格棋盤。現(xiàn)將"馬"放在任意指定的方格中,按照"馬"走棋的規(guī)則將"馬"進行移動。要求每個方格只能進入一次,最終使得"馬"走遍棋盤的64個方格。

【算法分析】

  ① 在四角,馬踏日走只有兩個選擇;

  ② 在其余部分,馬踏日走有四、六、八不等的選擇。

解決方案:在外層另外加上兩層,確保 8*8 方格中的每一個格子都有8中不同的選擇;

重點:為了確保每個格子能走日字,而且選擇的可能性等同,初始化除了最外兩層格子標記沒有被訪問,最外兩層中每個格子都標記為已被訪問即可達到目標!

解釋:圖片中標記紅色的區(qū)域,初始化時就默認為馬已踏日字,集已被訪問,而中間的 8*8 的表格標記為馬未被訪問!

并且每一個表格中馬在訪問時都有8中不同的選擇,這8中不同的選擇都會在其相應(yīng)的x和y坐標上進行追加標記;

這8中選擇方式為:

【代碼展示1】:遞歸求解(回溯法求解),列出所有的解,并從中找出從(2,2)位置出發(fā)的合適解:

#include <iostream>
#include <stdlib.h>
?
using namespace std;
?
int chessboard[12][12] = {0};
?
int cnt = 0;?? ??? ??? ?//標記馬已走的方格數(shù)
int sum = 0;?? ??? ??? ?//標記馬走完全程的具體方案數(shù)
int move[8][2]={ {2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};?? ?//初始馬當前位置向其周圍相鄰八個日字的 x,y的偏移量
?
//輸出馬踏棋盤的解?
void PrintChess();
//馬踏棋盤遞歸過程
void Horse(int x,int y);?
?
int main(void){
?? ?int i,j;
?? ?for(i=0;i<12;i++){
?? ??? ?for(j=0;j<12;j++){
?? ??? ??? ?if(i==0 || i==1 || i==10 || i==11 || j==0 || j==1 || j==10 || j==11){
?? ??? ??? ??? ?chessboard[i][j]=-1;//在 8 * 8 的外層再加上兩層,確保 8 * 8 方格中的每一個格子都有 8 種不同的日字選擇?
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?//從起始位置開始求得所有解
?? ?chessboard[2][2] = ++cnt;
?? ?Horse(2,2);?? ?//遞歸調(diào)用當前當前位置附近的 8 個日字,看看是否滿足條件
?? ?return 0;?
}?
?
void Horse(int x,int y){?? ??? ?//馬永遠踏的是 x,y位置,而不是 a,b?
?? ?if(cnt >= 64){?? ??? ?//臨界值,馬走日字全部踏完,成功求出問題解?? ??
?? ??? ?sum++;
?? ??? ?PrintChess();
?? ??? ?return;
?? ?}?
?? ?for(int i=0;i<8;i++){
?? ??? ?int a = x + move[i][0];?? ??? ?//拿到當前馬位置相鄰的 8 個日字的 x 坐標?
?? ??? ?int b = y + move[i][1];?? ??? ?//拿到當前馬位置相鄰的 8 個日字的 y 坐標?
?? ??? ?if(chessboard[a][b] == 0){?? ?//判斷當前馬位置相鄰的日字是否已被訪問?
?? ??? ??? ?cnt++;?? ??? ??? ??? ??? ??
?? ??? ??? ?chessboard[a][b]=cnt;?? ?//標志已被訪問
?? ??? ??? ?Horse(a,b);?? ??? ??? ? ?? ?//從當前馬的位置繼續(xù)往下訪問
?? ??? ??? ?cnt--;?? ??? ??? ??? ??? ?
?? ??? ??? ?chessboard[a][b]=0; ?? ?//回溯回來修改其相鄰的日字的訪問情況?
?? ??? ?}
?? ?}
}
?
//輸出馬踏棋盤的解?
void PrintChess(){
?? ?cout<<endl<<"馬踏棋盤第 "<<sum<<"組解為:"<<endl;
?? ?int i,j;
?? ?for(i=2;i<10;i++){
?? ??? ?for(j=2;j<10;j++){
?? ??? ??? ?cout<<" ?"<<chessboard[i][j];?
?? ??? ?}
?? ??? ?cout<<endl;
?? ?}?
}

【問題的解】:只列出量兩組解,其余未列出:

【代碼展示2】:貪心算法求解,列出從(2,2)位置出發(fā)的合適解,局部最優(yōu):

#include <iostream>
#include <stdlib.h>
?
using namespace std;
?
/*?
typedef struct{
?? ?int x;?? ??? ??? ?//記錄當前馬位置的 x 坐標?? ??? ?
?? ?int y;?? ??? ??? ?//記錄當前馬位置的 y 坐標?
?? ?int i;?? ??? ??? ?//記錄從當前馬的位置前往下一個日字的序號 i (0<i<8)?
}StackHorse;?
*/
?
int StackHorse[100][3]={0};?? ??? ??? ?//申請一個??臻g(里面存儲的就是 x,y,i三個具體的變量值),來標記馬走的具體位置?
int chessboard[12][12] = {0};?? ??? ?//記錄 8 * 8棋盤馬走的具體腳印?
int cnt = 1;?? ??? ??? ?//標記馬已走的方格數(shù)
int move[8][2]={ {2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};?? ?//初始馬當前位置向其周圍相鄰八個日字的 x,y的偏移量
?
//輸出馬踏棋盤的解?
void PrintChess();
//馬踏棋盤遞歸過程
void Horse(int x,int y);
?
int main(void){
?? ?int i,j;
?? ?for(i=0;i<12;i++){?? ??? ?//初始化馬踏棋盤的具體值(0代表未被訪問,1代表已被訪問,-1代表新加的最外面兩層)?
?? ??? ?for(j=0;j<12;j++){
?? ??? ??? ?if(i==0 || i==1 || i==10 || i==11 || j==0 || j==1 || j==10 || j==11){
?? ??? ??? ??? ?chessboard[i][j]=-1;
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?Horse(2,2);?? ??? ?//從 (2,2)的位置開始跑,求得馬踏棋盤的一組解
?? ?PrintChess();
?? ?return 0;?
}?
?
//非遞歸求一組解的過程
void Horse(int x,int y){
?? ?int top=0,i=0;
?? ?int a,b;?? ??? ??? ??? ?//記錄當前馬位置附近的日字坐標
?? ?chessboard[x][y]=1;?? ?//標記當前起始位置已被訪問?
?
?? ?StackHorse[top][0]=StackHorse[top][1]=2;?? ?//記錄當前馬的位置
?? ?while(cnt < 64){
?? ??? ?for(;i<8;i++){
?? ??? ??? ?a = x + move[i][0];
?? ??? ??? ?b = y + move[i][1];
?? ??? ??? ?if(chessboard[a][b] == 0){?? ??? ?//如果當前馬位置附近的日字沒有被訪問?
?? ??? ??? ??? ?break;?? ??? ??? ??? ??? ??? ?//跳出循環(huán)?
?? ??? ??? ?}
?? ??? ?}
?? ??? ?if(i<8){?? ??? ??? ??? ??? ?//能夠訪問當前馬位置附近的日字?
?? ??? ??? ?chessboard[a][b]=++cnt;
?? ??? ??? ?StackHorse[top][2]=i;?? ?//記錄訪問當前馬位置附近的日字序號(0<i<8)
?? ??? ??? ?top++;?? ??? ??? ??? ??? ?//top指向新的棧頂
?? ??? ??? ?StackHorse[top][0]=a;?? ?//向新的棧頂放入馬踏入的 x坐標?? ?
?? ??? ??? ?StackHorse[top][1]=b;?? ?//向新的棧頂放入馬踏入的 y坐標?
?? ??? ??? ?x=a;?? ??? ??? ??? ??? ?//標記新的 x?
?? ??? ??? ?y=b;?? ??? ??? ??? ??? ?//標記新的 y?
?? ??? ??? ?i=0; ?? ??? ??? ??? ??? ?//從棧頂馬位置開始尋找附近的 8 個日字?
?? ??? ?}
?? ??? ?else{?? ??? ??? ?//沒有在當前馬位置附近找到符合條件的日字 ?
?? ??? ??? ?cnt--;?? ??? ??? ??? ?//回溯?
?? ??? ??? ?chessboard[x][y]=0;
?? ??? ??? ?top--;?? ??? ?//出棧
?? ??? ??? ?x=StackHorse[top][0];?? ??? ?//拿到當前馬位置的 x 坐標 ?
?? ??? ??? ?y=StackHorse[top][1];?? ??? ?//拿到當前馬位置的 y 坐標?
?? ??? ??? ?i=StackHorse[top][2];?? ??? ?//拿到當前馬位置前往下一日字的序號?
?? ??? ??? ?i++; ?? ??? ??? ??? ??? ??? ?//繼續(xù)搜索從當前馬位置訪問的日字序號的下一位置繼續(xù)訪問?
?? ??? ?}?
?? ?}?
?? ?
}?
?
//輸出馬踏棋盤的解?
void PrintChess(){
?? ?cout<<"馬踏棋盤一組解為:"<<endl;
?? ?int i,j;
?? ?for(i=2;i<10;i++){
?? ??? ?for(j=2;j<10;j++){
?? ??? ??? ?cout<<" ?"<<chessboard[i][j];?
?? ??? ?}
?? ??? ?cout<<endl;
?? ?}?
}

【問題的解】:列出一組解:

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • json error: Use of overloaded operator [] is ambiguous錯誤的解決方法

    json error: Use of overloaded operator [] is ambiguous錯誤的解決方

    今天小編就為大家分享一篇關(guān)于json error: Use of overloaded operator [] is ambiguous錯誤的解決方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • C語言如何求整數(shù)的位數(shù)及各位數(shù)字之和

    C語言如何求整數(shù)的位數(shù)及各位數(shù)字之和

    這篇文章主要介紹了C語言如何求整數(shù)的位數(shù)及各位數(shù)字之和,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Unity3D實現(xiàn)經(jīng)典小游戲Pacman

    Unity3D實現(xiàn)經(jīng)典小游戲Pacman

    這篇文章主要介紹了基于Unity3D制作一做個經(jīng)典小游戲Pacman,文中的示例代碼講解詳細,對我們學習Unity3D有一定的幫助,感興趣的小伙伴可以了解一下
    2021-12-12
  • C++模板編程特性之移動語義

    C++模板編程特性之移動語義

    首先,移動語義和完美轉(zhuǎn)發(fā)這兩個概念是在C++的模板編程的基礎(chǔ)上,新增的特性,主要是配合模板來使用。本篇會從C++的值類型,到移動拷貝與移動賦值來理解移動語義與完美轉(zhuǎn)發(fā)
    2022-08-08
  • 基于MATLAB神經(jīng)網(wǎng)絡(luò)圖像識別的高識別率代碼

    基于MATLAB神經(jīng)網(wǎng)絡(luò)圖像識別的高識別率代碼

    今天小編就為大家分享一篇關(guān)于基于MATLAB神經(jīng)網(wǎng)絡(luò)圖像識別的高識別率代碼,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • C語言?使用qsort函數(shù)來進行快速排序

    C語言?使用qsort函數(shù)來進行快速排序

    排序方法有很多種:選擇排序,冒泡排序,歸并排序,快速排序等。?看名字都知道快速排序是目前公認的一種比較好的排序算法。因為他速度很快,所以系統(tǒng)也在庫里實現(xiàn)這個算法,便于我們的使用。?這就是qsort函數(shù)
    2022-02-02
  • 詳細談?wù)凜語言中動態(tài)內(nèi)存

    詳細談?wù)凜語言中動態(tài)內(nèi)存

    在C語言中,編寫程序的時候不能確定內(nèi)存的大小,希望程序在運行的過程中根據(jù)數(shù)據(jù)量的大小動態(tài)的分配內(nèi)存,這篇文章主要給大家介紹了關(guān)于C語言中動態(tài)內(nèi)存的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • Qt實現(xiàn)卡牌對對碰游戲(附demo)

    Qt實現(xiàn)卡牌對對碰游戲(附demo)

    本文主要介紹了Qt實現(xiàn)卡牌對對碰游戲,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-10-10
  • VSCode如何使用最新的C++20(推薦)

    VSCode如何使用最新的C++20(推薦)

    這篇文章主要介紹了VSCode使用最新的C++20的相關(guān)知識,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • C++約瑟夫環(huán)問題詳解

    C++約瑟夫環(huán)問題詳解

    大家好,本篇文章主要講的是C++約瑟夫環(huán)問題詳解 ,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01

最新評論