數據結構 第10講 好玩貪喫蛇——數字矩陣

數據結構 第10講 好玩貪喫蛇——數字矩陣

 

上題目:



這是螺旋狀的分佈啊,有點像棒棒糖上面的圓圈圈。那麼怎麼解呢?

一種思路:先填外圍一圈,然後把內部看作一個子問題,繼續填充。

即前面的4*n-4個元素順時針填充外圍,

剩下的問題變成用後面的元素填充一個規模爲n-2的子問題。

再用剩餘元素的前面4*(n-2)-4個元素順時針填充規模爲n-2的子問題外圍,

剩下的問題變成用後面的元素填充一個規模爲n-4的更小的子問題

……

依次類推。

n=1時填唯一的一個數即可。

換一種思路:把放出一個好玩的貪喫蛇,按照右下左上的順序喫蛋糕,一邊喫蛋糕,一邊拉數字,多喫一個蛋糕,拉出的數字多1,直到把所有的蛋糕喫完。


當貪喫蛇把小蛋糕喫完的時候,畫風就變成了這樣:


那麼程序設計怎麼做呢?

因爲貪喫蛇出動按照右下左上四個方向,因此先定義一個方向偏移數組:

向右:行+0,列+1偏移量:DIR[0].x=0; DIR[0].y=1;

向下:行+1,列+0偏移量:DIR[1].x=1; DIR[1].y=0;

向左:行+0,列-1偏移量:DIR[2].x=0; DIR[2].y=-1;

向上:行-1,列+0偏移量:DIR[3].x=-1; DIR[3].y=0;

定義了偏移數組後,就可以從左上角開始,先向右走,只要有蛋糕或未到邊界就繼續前進,否則選擇下一個方向,一直走下去,直到拉出的數字達到最大值n2,算法停止。

那麼你怎麼知道有沒有蛋糕呢?

因爲吃了蛋糕後,這個方格就變成了一個大於零的數字,因此我們可以設置爲0時有蛋糕。


那麼你怎麼知道有沒有到達邊界呢?

四周封鎖:


做了封鎖之後,小貪喫蛇再也不用擔心跑出邊界了,它只需要按照右下左上的方向,只吃有蛋糕的格子(0)就可以了。

源碼:

#include <iostream>
#include <algorithm>
using namespace std;
 
typedef struct
{
int x;
int y;
} Position;//位置
 
int m[30][30];//地圖
Position here,next;//當前位置,下一個位置
Position DIR[4]={0, 1, 1, 0, 0, -1, -1, 0};//右下左上方向數組
 
void Init(int n)
{
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++) //方格陣列初始化爲0
        m[i][j]=0;
    }
    for(int j=0; j<=n+1; j++) //方格陣列上下圍牆
        m[0][j]=m[n+1][j]=-1;
    for(int i=0; i<=n+1; i++) //方格陣列左右圍牆
        m[i][0]=m[i][n+1]=-1;
}
 
void Print(int start,int endi)//start, endi爲開始和結束下標
{
    for (int i=start; i<=endi; i++)
    {
        cout<<m[i][start];
        for (int j=start+1; j<=endi; j++)
        {
            cout<<"\t"<<m[i][j];
        }
        cout<<endl;
    }
    cout<<endl;
}
 
// n:原問題規模
// m:地圖矩陣
void Solve(int n)
{
    here.x=1;//左上角有蛋糕的位置
    here.y=1;
    int dirIndex=0;
    int num=1;
    m[1][1]=1;
    while(num<n*n)
    {
        next.x=here.x+DIR[dirIndex].x;
        next.y=here.y+DIR[dirIndex].y;
        if(m[next.x][next.y]==0) //判斷下一個位置是否有蛋糕
        {
            m[next.x][next.y]=++num; //吃了蛋糕,拉出的數字加1
            here=next; //以next爲當前位置,繼續走
         }
         else
        dirIndex=(dirIndex+1)%4;//換下一個方向,按右下左上順序繼續喫蛋糕
    }
}
 
 
int main()
{
    int n=0;
    cout<<"請輸入大於1小於等於20的整數n:"<<endl;
    cin>>n;
    while(n<1||n>20)
    {
       cout<<"請輸入大於1小於等於20的整數n:"<<endl;
       cin>>n;
    }
    Init(n);
    Print(0,n+1);
    Solve(n);
    Print(1,n);
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章