APCS程式檢測 -實作題1060304 第3題 數字龍捲風

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;
}

依照題目輸入範例

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *