APCS程式檢測 -實作題1060304 第3題 數字龍捲風
如果不清楚二維陣列,可以先來這裡看看
https://husking-studio.com/cpp-2d-array/
第一步:對方向做處理
//定義方向常數
const int LEFT = 0; //左
const int UP = 1; //上
const int RIGHT = 2; //右
const int DOWN = 3; //下
//順時針的下一個方向
int GetNextDirection(int nDir)
{
if (nDir == DOWN)
return LEFT;
return nDir + 1;
}
//方向改變時,索引值的變化(row)
int GetRowDelta(int nDir)
{
if (nDir == RIGHT)
return 0;
else if (nDir == DOWN)
return 1;
else if (nDir == LEFT)
return 0;
else if (nDir == UP)
return -1;
return 0;
}
//方向改變時,索引值的變化(column)
int GetColDelta(int nDir)
{
if (nDir == RIGHT)
return 1;
else if (nDir == DOWN)
return 0;
else if (nDir == LEFT)
return -1;
else if (nDir == UP)
return 0;
return 0;
}
第二步:要向哪個方向走幾格的陣列
稍微研究一下會發現,這個陣列會是 (N – 1) * 2 + 1 個值
//產生走幾格的陣列
int nStepArrayNum = (N - 1) * 2 + 1;
int* nStepArray = new int[nStepArrayNum];
int k = 1;
for (int i = 0; i < (nStepArrayNum - 1); i = i + 2)
{
nStepArray[i] = k;
nStepArray[i + 1] = k;
k++;
}
nStepArray[nStepArrayNum - 1] = N - 1;
TestPrint01(nStepArray, nStepArrayNum, nStartDir);
void TestPrint01(int *pStepArray, int nNum, int nStartDir)
{
int nDir = nStartDir;
for (int i = 0; i < nNum; i++)
{
if (nDir == RIGHT)
cout << "向右走 " << pStepArray[i] <<" 格" << endl;
else if (nDir == DOWN)
cout << "向下走 " << pStepArray[i] << " 格" << endl;
else if (nDir == LEFT)
cout << "向左走 " << pStepArray[i] << " 格" << endl;
else if (nDir == UP)
cout << "向上走 " << pStepArray[i] << " 格" << endl;
nDir = GetNextDirection(nDir);
}
}
執行結果
向左走 1 格 向上走 1 格 向右走 2 格 向下走 2 格 向左走 3 格 向上走 3 格 向右走 4 格 向下走 4 格 向左走 4 格 |
第三步:再來產生箭頭方向陣列,會有 N * N – 1 個箭頭
//產生箭頭方向陣列
int nDir = nStartDir;
int* nArrowArray = new int[N * N - 1];
int p = 0;
while (p < (N * N - 1))
{
for (int j = 0; j < nStepArrayNum; j++)
{
for (int k = 0; k < nStepArray[j]; k++)
{
nArrowArray[p] = nDir;
p++;
}
nDir = GetNextDirection(nDir);
}
}
TestPrint02(nArrowArray, N * N - 1, nDir);
void TestPrint02(int *pArrowArray, int nNum, int nStartDir)
{
int nDir = nStartDir;
for (int i = 0; i < nNum; i++)
{
if (pArrowArray[i] == RIGHT)
cout << "右";
else if (pArrowArray[i] == DOWN)
cout << "下";
else if (pArrowArray[i] == LEFT)
cout << "左";
else if (pArrowArray[i] == UP)
cout << "上";
nDir = GetNextDirection(nDir);
}
cout << endl;
}
執行結果
左上右右下下左左左上上上右右右右下下下下左左左左 |
第四步:把陣列索引跟箭頭方向陣列做計算
//把陣列索引跟箭頭方向陣列做計算
int* nRow = new int[N * N];
int* nCol = new int[N * N];
nRow[0] = N / 2;
nCol[0] = N / 2;
for (int i = 1; i < N * N; i++)
nRow[i] = nRow[i - 1] + GetRowDelta(nArrowArray[i - 1]);
for (int i = 1; i < N * N; i++)
nCol[i] = nCol[i - 1] + GetColDelta(nArrowArray[i - 1]);
TestPrint03(nRow, nCol, N * N);
void TestPrint03(int *pRow, int* pCol, int nNum)
{
for (int i = 0; i < nNum; i++)
cout << "[" << pRow[i] << "][" << pCol[i] << "]" << endl;
}
執行結果
[2][2] [2][1] [1][1] [1][2] [1][3] [2][3] [3][3] [3][2] [3][1] [3][0] [2][0] [1][0] [0][0] [0][1] [0][2] [0][3] [0][4] [1][4] [2][4] [3][4] [4][4] [4][3] [4][2] [4][1] [4][0] |
完整程式碼
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
const int LEFT = 0; //左
const int UP = 1; //上
const int RIGHT = 2; //右
const int DOWN = 3; //下
int GetNextDirection(int nDir);
int GetRowDelta(int nDir);
int GetColDelta(int nDir);
int main()
{
//輸入個數
string str2;
getline(cin, str2);
int N = stoi(str2);
//輸入方向
string str3;
getline(cin, str3);
int nStartDir = stoi(str3);
//動態宣告二維陣列
int** data;
data = new int* [N];
for (int i = 0; i < N; i++)
data[i] = new int[N];
//輸入陣列資料
string str;
for (int i = 0; i < N; i++)
{
getline(cin, str);
stringstream delim(str);
string pch;
for (int j = 0; j < N; j++)
{
getline(delim, pch, ' ');
data[i][j] = stoi(pch);
}
}
//產生走幾格的陣列
int nStepArrayNum = (N - 1) * 2 + 1;
int* nStepArray = new int[nStepArrayNum];
int k = 1;
for (int i = 0; i < (nStepArrayNum - 1); i = i + 2)
{
nStepArray[i] = k;
nStepArray[i + 1] = k;
k++;
}
nStepArray[nStepArrayNum - 1] = N - 1;
//產生箭頭方向陣列
int nDir = nStartDir;
int* nArrowArray = new int[N * N - 1];
int p = 0;
while (p < (N * N - 1))
{
for (int j = 0; j < nStepArrayNum; j++)
{
for (int k = 0; k < nStepArray[j]; k++)
{
nArrowArray[p] = nDir;
p++;
}
nDir = GetNextDirection(nDir);
}
}
//把陣列索引跟箭頭方向陣列做計算
int* nRow = new int[N * N];
int* nCol = new int[N * N];
nRow[0] = N / 2;
nCol[0] = N / 2;
for (int i = 1; i < N * N; i++)
nRow[i] = nRow[i - 1] + GetRowDelta(nArrowArray[i - 1]);
for (int i = 1; i < N * N; i++)
nCol[i] = nCol[i - 1] + GetColDelta(nArrowArray[i - 1]);
//印出答案
for (int i = 0; i < N * N; i++)
cout << data[nRow[i]][nCol[i]];
cout << endl;
//最後要記得做 delete
for (int i = 0; i < N; i++)
delete[] data[i];
delete[] data;
delete[] nStepArray;
delete[] nArrowArray;
delete[] nRow;
delete[] nCol;
system("pause");
return 0;
}
//順時針的下一個方向
int GetNextDirection(int nDir)
{
if (nDir == DOWN)
return LEFT;
return nDir + 1;
}
//方向改變時,索引值的變化(row)
int GetRowDelta(int nDir)
{
if (nDir == RIGHT)
return 0;
else if (nDir == DOWN)
return 1;
else if (nDir == LEFT)
return 0;
else if (nDir == UP)
return -1;
return 0;
}
//方向改變時,索引值的變化(column)
int GetColDelta(int nDir)
{
if (nDir == RIGHT)
return 1;
else if (nDir == DOWN)
return 0;
else if (nDir == LEFT)
return -1;
else if (nDir == UP)
return 0;
return 0;
}
依照題目輸入範例