給出一個不大于 9 的正整數(shù) n,輸出 n×n 的蛇形方陣。
從左上角填上 1 開始,順時針方向依次填入數(shù)字,如同樣例所示。注意每個數(shù)字有都會占用 3 個字符,前面使用空格補齊。
輸入樣例輸入
4
輸出
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
題解部分涉及算法:模擬。
各位讀者有聽說過“建?!币辉~嗎?所謂“建?!保褪前咽挛镞M(jìn)行抽象,根據(jù)實際問題來建立對應(yīng)的數(shù)學(xué)模型。“抽象”并不意味著晦澀難懂;相反,它提供了大量的便利。計算機(jī)很難直接去解決實際問題,但是如果把實際問題建模成數(shù)學(xué)問題,就會大大地方便計算機(jī)來“理解”和“解決”。
思路
1.首先我們可以把題目抽象成數(shù)學(xué)問題,題目可以理解成為在一個方格里按一定規(guī)律填自然數(shù),規(guī)律如下圖。(畫的丑各位輕噴)
可以看出"小蛇"的走向是右、下、左、上、反復(fù)循環(huán)。
2.建模完畢之后,我們可以把這個矩陣用二維數(shù)組來表示,每填一個數(shù)就相當(dāng)于x或者y變化。
注意這個坐標(biāo)系的建立是根據(jù)二維數(shù)組的特性建立的x代表行、y代表列。
int map[15][15];
//雖然題目要求數(shù)據(jù)大是9*9,但為了避免內(nèi)存會爆一般會把數(shù)組空間開大一點。
for(i=1;i<=n*n;i++)
map[x][y]=i;
3.那如何控制方向呢?其實只需要再定義一個二維數(shù)組就可以啦,這個數(shù)組,我們稱之為偏移量數(shù)組。
int pos[4][2]={{0,1), //向右填數(shù)
{1,0},//向下填數(shù)
{0,-1},//向左填數(shù)
{-1,0}};//向上填數(shù)
注意順序一定要按小蛇的走向規(guī)律填寫。
為了方便大家理解,可以來看下面這張圖,正好與上面的源碼對應(yīng)。
通過這個方向數(shù)組,我們就很容易獲得下一步的坐標(biāo)。這里可以用tx,ty來表示。
int tx=x+t[d][0];
int ty=y+t[d][1];
///通過改變d來改變方向。
4.如何判斷下一步要不要換方向呢?這時,tx,ty就派上用場了。
我們需要判斷tx、ty是否超出邊界,來決定是否轉(zhuǎn)向。
for(i=1;i<=n*n;i++)
{map[x][y]=i;
tx=x+pos[d][0],ty=y+pos[d][1];//先沿著原來方向走,看看合不合法。
if(tx>n||ty>n||tx<1||ty<1||map[tx][ty]>0)
d=(d+1)%4;//因為只有四個方向所以d++時需要%4,使得d只能是0,1,2,3。
x=x+pos[d][0],y=y+pos[d][1];//判斷完畢后就可以知道下一步填哪啦。
}
矩陣的大小為n*n,故邊界為[1,n]。
所以一旦tx,ty,超出邊界,就需轉(zhuǎn)向。
即tx>n||ty>n||tx<1||ty<1
。
需要注意的是遇到之前已經(jīng)填過數(shù)字的方格也需要轉(zhuǎn)向。
即map[tx][ty]>0
。
ok核心部分已經(jīng)講解完畢,下面附上完整代碼。
完整代碼C語言版
#includeint map[15][15];//需要定義在全局變量,好處是初始化默認(rèn)值都是0。
int pos[4][2]={0,1,1,0,0,-1,-1,0};
int main()
{int n;
int i,j;
scanf("%d",&n);
int x=1,y=1,d=0;
for(i=1;i<=n*n;i++)
{map[x][y]=i;
int tx=x+pos[d][0],ty=y+pos[d][1];
if(tx>n||ty>n||tx<1||ty<1||map[tx][ty]>0)
d=(d+1)%4;
x=x+pos[d][0],y=y+pos[d][1];
}
for(i=1;i<=n;i++)
{for(j=1;j<=n;j++)
printf("%3d",map[i][j]);
printf("\n");
}
return 0;
}
C++版
#includeusing namespace std;
int g[15][15];
int pos[4][2]={0,1,1,0,0,-1,-1,0};
int main()
{int n;
cin>>n;
int i,j;
int x=1,y=1,d=0;
for(i=1;i<=n*n;i++)
{g[x][y]=i;
int tx=x+pos[d][0],ty=y+pos[d][1];
if(tx>n||ty>n||tx<1||ty<1||g[tx][ty])
d=(d+1)%4;
x=x+pos[d][0],y=y+pos[d][1];
}
for(i=1;i<=n;i++)
{for(j=1;j<=n;j++)
printf("%3d",g[i][j]);
cout<
最近剛接觸的C++,不過單從這題來看好像也差不多(捂臉)。
完結(jié)散花太感謝你能看到這兒啦。
因為是第一次嘗試寫博客,可能寫的有點啰嗦,但是真心希望可以幫助到你,如果有更優(yōu)化簡潔的代碼也歡迎評論區(qū)交流。
悄悄告訴你:現(xiàn)在關(guān)注我,以后咱就是老粉啦。
最后的一句話送給各位以及以后再翻這篇博客的自己:
“希望不忘初心,牢記勤能補拙?!?/p>參考文章
https://blog.csdn.net/m0_46549425/article/details.
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧