如果所示,逆時針填充正方形,從1,2,3…到16,輸入一個正方形的大小,填充。
比如輸入4,正方形如上圖,如果輸入5,則是1,2,3…到25。
這道題,可以按照如圖所示的方法,先構造最外一圈的數,123一組,456一組,789一組,101112一組,只需要注意到下標的變化,數字的更新即可。對於裏面矩陣可以採用遞歸的寫法。
void FillTheRectangle_1(vector<vector<int>>& v, int size, int beg, int num)
{
if (beg < 0 || size == 0)
return;
if (size == 1)
{
v[beg][beg] = num;
return;
}
//size >= 2
//左邊
for (int i = 0; i < size - 1; i++)
{
v[beg + i][beg] = num++;
}
//下邊
for (int j = 0; j < size - 1; j++)
{
v[beg + size - 1][j + beg] = num++;
}
//右邊
for (int i = 0; i < size - 1; i++)
{
v[beg + size - 1 - i][beg + size - 1] = num++;
}
//上邊
for (int j = 0; j < size - 1; j++)
{
v[beg][beg + size - 1 - j] = num++;
}
FillTheRectangle_1(v, size - 2, beg + 1, num);
}
這裏我採用左下右上的順序,依次相加num填充。不過細心一看代碼,你會發現,四個for循環條件都是相同的,因此,我們可以考慮合併一下啊,但是這裏需要考慮對應的num,它不再是直接++操作,對於num,我們舉例來分析,比如當i = 0時,此時四個邊角的數字爲
1 4 7 10
很容易發現,他們是等差數列,公差爲正方形的size-1=3
因此,更精簡的代碼如下:
void FillTheRectangle_2(vector<vector<int>>& v, int size, int beg, int num)
{
if (beg < 0 || size == 0)
return;
if (size == 1)
{
v[beg][beg] = num;
return;
}
//size >= 2
for (int i = 0; i < size - 1; i++)
{
v[beg + i][beg] = num + i;
v[beg + size - 1][i + beg] = num + (size - 1) + i;
v[beg + size - 1 - i][beg + size - 1] = num + 2 * (size - 1) + i;
v[beg][beg + size - 1 - i] = num + 3 * (size - 1) + i;
}
FillTheRectangle_2(v, size - 2, beg + 1, num + 4 * (size - 1));
}
測試一下!
int main()
{
//vector<int> v = { 5, 10, 25, 1 };
int size = 5;
vector<vector<int>> v(size, vector<int>(size));
FillTheRectangle_1(v, size, 0, 1);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
cout << v[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
size = 4;
vector<vector<int>> v1(size, vector<int>(size));
FillTheRectangle_2(v1, size, 0, 1);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
cout << v1[i][j] << " ";
}
cout << endl;
}
return 0;
}
結果是正確的: