1. 程式人生 > >T:求金屬熔化所需要的時間(C++)

T:求金屬熔化所需要的時間(C++)

習題內容:

求金屬融化所需要的時間

[1].在N × N的格子上放置著形狀不規則的金屬(5≤N≤1000)。

  1. 金屬為1×1格子的整數倍組成的不規則形狀;
  2. 金屬有可能中空,這樣在開始的時刻中空的方格不會立即充滿液體;
  3. 當中空的格子有缺口時,液體可以立即進入到中空的地方。

[2].T=0時刻從格子的最外圍開始注入某種可以融化金屬的液體。

  1. 液體擴散填充的速度不計,例如在T=0時刻液體充滿淺藍色方塊。

[3].當金屬塊上、下、左、右4個方向中至少有兩個方向鄰接液體的時候,金屬塊融化,耗時1個時間單位。

  1. 例如圖中標記為1的點為T=1時刻將要融化的點;
  2. 當金屬中空的部分暴露出來時,例如圖中的T=2時刻液體會立刻充滿可連線的中空部分,液體擴散的時間不計。如圖中在T=5的時刻金屬融化。

例 輸入:N=16

________________

__##____________

__########______

___####__#####__

___#_##___####__

___#_####_##____

_____########___

_______###______

________________

________________

____#######_____

_____######_____

______##__##____

_______#####____

________________

________________

輸出:5

提示:

1  輸入的圖對應的直觀效果如下所示。

2 液體與中空的符號是相同的,需要加以區別。

3 可以藉助於圖的遍歷演算法實現。

實現程式碼:

/*測試環境:VS2017*/

#include<iostream>
using namespace std;

static int N, T;//N:邊長;T:時間
char **arry;//以二維陣列的形式記錄金屬形態

void Input()
{
	cout << "請輸入整數N(5≤N≤1000)及其分佈:" << endl;
	cin >> N;
	arry = new char*[N];
	for (int i = 0; i < N; i++)
		arry[i] = new char[N];
	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			cin >> arry[i][j];
}

void Output()
{
	cout << endl;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
			cout << arry[i][j];
		cout << endl;
	}
	cout << endl;
}

//判斷中空的格子‘_’--->‘*’
void Judge()
{
	for (int m = 0; m < N; m++)
		for (int n = 0; n < N; n++)
		{
			if (arry[m][n] == '_'&&m>0 && n>0 && m<N - 1 && n<N - 1)
			{
				int x = 0;
				int I1 = m, I2 = m, J1 = n, J2 = n;

				//根據‘_’四個方向上是否都有‘#’來初步判斷是否中空
				while (I1 > -1)
				{
					if (arry[I1--][n] == '#')
					{
						x++;
						break;
					}
				}
				while (I2 <N)
				{
					if (arry[I2++][n] == '#')
					{
						x++;
						break;
					}
				}
				while (J1>-1)
				{
					if (arry[m][J1--] == '#')
					{
						x++;
						break;
					}
				}
				while (J2<N)
				{
					if (arry[m][J2++] == '#')
					{
						x++;
						break;
					}
				}
				if (x == 4)
					arry[m][n] = '*';
			}
		}

	//篩選出中空的格子
	while (1)
	{
		int l = 0;
		for (int i = 0; i < N; i++)
			for (int j = 0; j < N; j++)
			{
				if (arry[i][j] == '_')
				{
					if (i>0 && arry[i - 1][j] == '*')
					{
						l++;
						arry[i - 1][j] = '_';
					}
					if (i < N - 1 && arry[i + 1][j] == '*')
					{
						l++;
						arry[i + 1][j] = '_';
					}
					if (j>0 && arry[i][j - 1] == '*')
					{
						l++;
						arry[i][j - 1] = '_';
					}
					if (j < N - 1 && arry[i][j + 1] == '*')
					{
						l++;
						arry[i][j + 1] = '_';
					}
				}
			}
		if (l == 0)
			break;
	}
}

//"融化"操作
void Melt()
{
	T = 0;
	while (1)
	{
		int count = 0;
		for (int i = 0; i < N; i++)
			for (int j = 0; j < N; j++)
				if (arry[i][j] != '_')
					count++;
		if (count == 0)
			break;

		for (int m = 0; m < N; m++)
			for (int n = 0; n < N; n++)
			{
				if (arry[m][n] == '#')
				{
					int x = 0;
					if (m>0 && arry[m - 1][n] == '_')
						x++;
					if (m<N - 1 && arry[m + 1][n] == '_')
						x++;
					if (n>0 && arry[m][n - 1] == '_')
						x++;
					if (n<N - 1 && arry[m][n + 1] == '_')
						x++;
					if (x>1)
						arry[m][n] = '1';
				}
			}
		for (int m = 0; m < N; m++)
			for (int n = 0; n < N; n++)
				if (arry[m][n] == '1')
					arry[m][n] = '_';

		T++;
		Judge();
		cout <<"T="<<T << endl;
		Output();
	}
	cout << T;
	system("pause");
}

int main()
{
	Input();
	Judge();
	Output();
	Melt();
}