1. 程式人生 > >【CCF CSP】 201412-2 Z字形掃描(100分)

【CCF CSP】 201412-2 Z字形掃描(100分)

試題編號:201412-2
試題名稱:Z字形掃描
時間限制:2.0s
記憶體限制:256.0MB
問題描述:問題描述  在影象編碼的演算法中,需要將一個給定的方形矩陣進行Z字形掃描(Zigzag Scan)。給定一個n×n的矩陣,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的正整數。

解析

將掃描方向抽出來,根據掃描的方向去確定選擇的數字。
根據題目可知,掃描總共有四個方向:遇到邊界時要判斷方向的走向

右,下,左下,右上

程式碼

C++

#include <iostream>
#include <vector> 
#define MAX_LENGTH 501
using namespace std;

enum Direction{Bottom,Bottom_left,Right,Top_right}flag;
int grad[MAX_LENGTH][MAX_LENGTH]; 

int main(int argc, char
** argv) { int n; vector<int> vec_Z; cin>>n; //輸入 for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cin>>grad[i][j]; } } //初始化第一個位置 int i=1,j=1; flag=Right; vec_Z.push_back(grad[1][1]); //開始Z掃描 for
(int k=1;k<n*n;k++) { switch(flag) { case Bottom: i++; vec_Z.push_back(grad[i][j]); //如果在左邊界,則左上;右邊界,則右下 if(j==1) flag=Top_right; else if(j==n) flag=Bottom_left; break; case Bottom_left: i++;j--; vec_Z.push_back(grad[i][j]); //到達左邊界時,換方向 下 if(j==1&&i!=n) flag=Bottom; else if(i==n) flag=Right; break; case Right: j++; vec_Z.push_back(grad[i][j]); if(i==1)//是否在上界 flag=Bottom_left; else if(i==n) flag=Top_right; break; case Top_right: i--;j++; vec_Z.push_back(grad[i][j]); //到達上界 方向為右邊 if(i==1&&j!=n) flag=Right; else if(j==n)//到達右界 ,方向向下 flag=Bottom; break; } } //輸出序列 for(vector<int>::iterator it=vec_Z.begin();it!=vec_Z.end();it++) cout<<*it<<' '; return 0; }