日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

信息学奥赛一本通 2045:【例5.13】蛇形填数

發布時間:2025/3/17 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信息学奥赛一本通 2045:【例5.13】蛇形填数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目鏈接】

ybt 2045:【例5.13】蛇形填數

【題目考點】

1. 二維數組

2. 方向數組(可能用到)

int dir[4][2] = {{1,0},{0,-1},{-1,0},{0,1}};
d為當前方向,0:下,1:左,2:上, 3:右
dir[d]為按d方向移動后橫縱坐標的變化量,即位置(x,y)按d方向移動到的下一個位置為(x+dir[d][0], y+dir[d][1])

【解題思路】

方法1:移動焦點位置

設二維數組,每個位置初值為0。設置關注的焦點位置(fx, fy),初始值為1,所在的位置(1, n)。用一個變量表示當前焦點移動方向,初值為向下。
首先將焦點位置賦值為1,焦點按照當前移動方向移動一次,然后將新的位置賦值為2,然后重復進行移動、賦值操作。如果移出二維數組范圍,或移動后焦點的位置已經有值了(不為0),那么就改變移動方向。移動方向按照下、左,上,右的順序循環變化。
可以用一個整數d表示方向,0:下 1:左 2:上 3:右。若想變為下一個方向,只需運行:d = (d + 1) % 4 即可。
該方法可以通過判斷當前方向做不同操作,或使用方向數組實現

方法2:按圈賦值

以圈為單位,從外向內進行遍歷、賦值。

  • 第1圈遍歷過程為:(1,n)向下到(n,n),(n, n-1)向左到(n, 1), (n-1, 1)向上到(1,1), (1,2)向右到(1, n-1)
  • 第2圈遍歷過程為:(2,n-1)向下到(n-1,n-1),(n-1, n-2)向左到(n-1, 2), (n-2, 2)向上到(2,2), (2,3)向右到(2, n-2)
  • 根據規律,第i圈遍歷過程為:(i, n-i+1)向下到(n-i+1,n-i+1),(n-i+1, n-i)向左到(n-i+1, i), (n-i, i)向上到(i,i), (i,i+1)向右到(i, n-i)
  • n為1時有1圈,n為2時有1圈,n為3時有2圈,n為4時有2圈…一共有?n2?\lceil \frac{n}{2} \rceil?2n??

【題解代碼】

解法1:移動焦點位置

  • 使用判斷語句判斷當前移動方向
#include<bits/stdc++.h> using namespace std; int main() {int a[25][25] = {}, n, fx, fy;//數組a各元素初值為0, fx,fy為焦點位置 int dir = 0;//表示方向 0:下 1:左 2:上 3:右cin >> n;//二維數組寬度 fx = 1, fy = n; //起始焦點位置(1, n) for(int i = 1; i <= n*n; ++i)//一共n*n個格子 {//數字i的位置是fx,fy a[fx][fy] = i;switch(dir)//判斷移動方向{case 0://下fx++;//焦點向下移動 if(fx == n || a[fx+1][fy] != 0)//如果已經到了第n行,或下一次要到的位置已經有值了 dir = (dir + 1) % 4;//移動方向變為下一個方向 break;case 1://左fy--;if(fy == 1 || a[fx][fy-1] != 0)dir = (dir + 1) % 4;break;case 2://上fx--;if(fx == 1 || a[fx-1][fy] != 0)dir = (dir + 1) % 4;break;case 3://右fy++;if(fy == n || a[fx][fy+1] != 0)dir = (dir + 1) % 4;break;}}for(int i = 1; i <= n; ++i)//輸出二維數組 {for(int j = 1; j <= n; ++j)cout << a[i][j] << ' ';cout << endl;}return 0; }
  • 使用方向數組
#include<bits/stdc++.h> using namespace std; int dir[4][2] = {{1,0},{0,-1},{-1,0},{0,1}};//方向數組 int main() {int a[25][25] = {}, k = 1, n, fx, fy, d = 0, x, y;//fx, fy當前焦點位置 x,y下一個位置 d:方向 cin >> n;fx = 1, fy = n;while(k <= n*n){a[fx][fy] = k++; // 賦值 x = fx + dir[d][0], y = fy + dir[d][1]; //下一個位置 if(a[x][y] != 0 || x > n || x < 1 || y > n || y < 1)//如果新位置上已經有值了或移出了二維數組范圍d = (d + 1) % 4;//變換方向 fx += dir[d][0], fy += dir[d][1];//更新焦點位置 }for(int i = 1; i <= n; ++i){for(int j = 1; j <= n; ++j)cout << a[i][j] << ' ';cout << endl;}return 0; }

解法2:按圈賦值

#include <bits/stdc++.h> using namespace std; int main() {int a[25][25], n, cnum, x, y, k = 1;cin >> n;cnum = ceil((double)n/2);//共有cnum圈 n為1,2時要遍歷1圈,n為3,4時要遍歷2圈。。。 ceil:向上取整 for(int i = 1; i <= cnum; i++)//第i圈 {for(x = i, y = n-i+1; x <= n-i+1; x++)//右上到右下 a[x][y] = k++; for(x = n-i+1, y = n-i; y >= i; y--)//右下到左下 a[x][y] = k++; for(x = n-i, y = i; x >= i; x--)//左下到左上 a[x][y] = k++; for(x = i, y = i+1; y <= n-i; y++)//左上到右上 a[x][y] = k++; }for(int i = 1; i <= n; i++)//輸出 {for(int j = 1; j <= n; j++)cout << a[i][j] << ' ';cout << endl;}return 0; }

總結

以上是生活随笔為你收集整理的信息学奥赛一本通 2045:【例5.13】蛇形填数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。