天天看點

CCF 201412-2 Z字形掃描 題解

試題編号: 201412-2
試題名稱: Z字形掃描
時間限制: 2.0s
記憶體限制: 256.0MB
問題描述: 問題描述   在圖像編碼的算法中,需要将一個給定的方形矩陣進行Z字形掃描(Zigzag Scan)。給定一個n×n的矩陣,Z字形掃描的過程如下圖所示:
CCF 201412-2 Z字形掃描 題解

  對于下面的4×4的矩陣,

  1 5 3 9

  3 7 5 6

  9 4 6 4

  7 3 1 3

  對其進行Z字形掃描後得到長度為16的序列:

  1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3

  請實作一個Z字形掃描的程式,給定一個n×n的矩陣,輸出對這個矩陣進行Z字形掃描的結果。 輸入格式   輸入的第一行包含一個整數n,表示矩陣的大小。

  輸入的第二行到第n+1行每行包含n個正整數,由空格分隔,表示給定的矩陣。 輸出格式   輸出一行,包含n×n個整數,由空格分隔,表示輸入的矩陣經過Z字形掃描後的結果。 樣例輸入 4

1 5 3 9

3 7 5 6

9 4 6 4

7 3 1 3 樣例輸出 1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3 評測用例規模與約定   1≤n≤500,矩陣元素為不超過1000的正整數。

思路:遞歸判斷選擇移動方式 移動方式: 開始  ↓  →  ↙  ↗ prvs對應值:-1   0   1   2   3

注意:n=1時是特例,需要判斷防止越界造成運作錯誤

滿分代碼:

#include <iostream>

using namespace std;

int n;
int a[505][505];

bool isBad(int h,int l) {	//位置越界判斷 
	return (h<0 || l<0 || h>=n ||l>=n);
}

bool PutMove(int prvs, int h, int l) {	//prvs代表經過什麼移動到達第h行、第l列的位置 
	if (prvs == -1){	//除第一個數以外,其他數加空格輸出 
		cout << a[h][l];
		if (!isBad(h,l+1))		//其右沒越界 
			PutMove(1,h,l+1);	//向右移動
	}		
	else
		cout << " " << a[h][l];
	if (h == n-1 && l == n-1)	//遞歸結束 
		return true;
	switch(prvs) {
		case 0:		//↓
			if (!isBad(h-1,l+1))	//其右上沒越界
				PutMove(3,h-1,l+1);	//向右上移動 
			else
				PutMove(2,h+1,l-1);	//向左下移動
			break;
		case 1:		//→ 
			if (!isBad(h+1,l-1))	//其左下沒越界
				PutMove(2,h+1,l-1);	//向左下移動			
			else
				PutMove(3,h-1,l+1);	//向右上移動 
			break;
		case 2:		//↙ 
			if (!isBad(h+1,l-1))	//其左下沒越界
				PutMove(2,h+1,l-1);	//向左下移動 
			else if (!isBad(h+1,l))	//其下沒越界 
				PutMove(0,h+1,l);	//向下移動 
			else
				PutMove(1,h,l+1);	//向右移動
			break;
		case 3:		//↗
			if (!isBad(h-1,l+1))	//其右上沒越界
				PutMove(3,h-1,l+1);	//向右上移動 
			else if (!isBad(h,l+1))	//其右沒越界 
				PutMove(1,h,l+1);	//向右移動
			else
				PutMove(0,h+1,l);	//向下移動 
			break;	
	} 
}

int main() {
	cin >> n;
	int i,j;
	for (i=0;i<n;i++)
		for (j=0;j<n;j++)
			cin >> a[i][j];
	PutMove(-1,0,0);
	return 0;
}