CCF软件认证题 java 201412-2 Z字型扫描

CCF软件认证题 java 201412-2 Z字型扫描

问题描述
  在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag Scan)。给定一个n×n的矩阵,Z字形扫描的过程如下图所示:
《CCF软件认证题 java 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的正整数。

思路想法

z字扫描,可以将动作拆分为水平往右,左下,竖直往下,右上,四个动作。关键在于在什么时候转换动作,转换为什么动作,什么时候结束以一个普通矩形为例,首先我们应该在左上角位置开始,然后水平往右一个单位,然后左下移动,触碰到左边界,往下移动一个单位,然后右上移动,触碰到上边界,然后开始循环,这个循环一直执行,其实是在扫描矩阵的左上角三角形。右下角的三角形该怎么扫描。当我们扫描到(这里指的是左下运动,跟右上运动的下一个元素)左下角,或者右上角元素时,转换动作就行了。比如扫描到左下角,下一步动作就是水平右移一个单位,开始右上运动。如果扫描到右上角,下一个动作是向下移动一个单位,开始左下运动。这样,扫描到右下角的元素,就可以退出了。其实当矩阵是偶数时,先扫描到时左下角,矩阵是奇数时,先扫描到的是右上角。这是后面我修改代码是才发现的。最后,还有一个特殊的矩阵,就是只有一个元素的矩阵。这个就不用扫描了,直接输出。

代码


import java.util.Scanner;

public class Main {

	/** * @param args */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input=new Scanner(System.in);
		int n= input.nextInt();
		int [][]array=new int [n][n];     //创建n*n的二维数组表示矩阵
		
		for(int i=0;i<n;i++){           //遍历录入数据
			for(int j=0;j<n;j++)      
				array[i][j]=input.nextInt();
		}
		int x=0,y=0;        //初始光标在0,0位置,
		int logo=1;
		System.out.print(array[x][y]+" ");    //先输出左上角元素
		if(n%2==0){              //判断矩阵为偶数矩阵
			while(true){
				if(logo==1){
					y++;          // 光标水平右移一个单位长度
					System.out.print(array[x][y]+" ");    //输出当前位置元素
					while(true){					    //光标往左下移动,一直移动到触碰左边界,或者下边界
							y--;
							x++;					
						System.out.print(array[x][y]+" ");				
						if(y==0)            //左边界判断,y=0
						break;						//跳出死循环,光标不再左下移动
					}
					if(x==n-1&&y==0){              //判断是否为左下角元素,左下角元素,改变logo执行另一个操作
						logo=2;
						continue;
					}
					x++;						//触碰左边界后,光标先向下移动一个单位,然后开始右上运动
					System.out.print(array[x][y]+" ");
					while(true){	           //死循环,右上运动
							y++;
							x--;			
					System.out.print(array[x][y]+" ");	
						if(x==0)      //直到触碰上边界,退出右上运动循环
						break;			
					}
				}
			
			if(logo==2){			//偶数矩阵到达左下角后应该,往右移动一个单位先,再进行右上移动
				y++;
				System.out.print(array[x][y]+" ");

				if(x==n-1&&y==n-1)        //注意是否达到右下角,达到退出结束。
					break;
				while(true){			//未到右下角,执行右上移动 
						y++;
						x--;			
					System.out.print(array[x][y]+" ");
					if(y==n-1)     //判断是否达到右边界,到达退出右上运动
					break;
				}	
				x++;               //往下移动一个单位
				System.out.print(array[x][y]+" ");
				while(true){	//开始左下运动 
						y--;
						x++;			
				System.out.print(array[x][y]+" ");				
					if(x==n-1)  //判断是否到达下边界
					break;		//退出左下运动
				}		
			}
			
		  }	
		}else{
			while(true){
				if(n==1){   //判断是否为特殊矩形,1*1,如果是,则不进行扫描,因为光标初始时已经输出。
				break;
				}
				if(logo==1){
					y++;       //右移一个单位
					System.out.print(array[x][y]+" ");
					while(true){	//左下运动 
							y--;
							x++;					
						System.out.print(array[x][y]+" ");				
						if(y==0)    //达到左边界,退出运动
						break;
					}
				
					x++;          //向下移动一个单位
					System.out.print(array[x][y]+" ");
					while(true){	//右上运动
							y++;
							x--;			
					System.out.print(array[x][y]+" ");			
						if(x==0)    //达到上边界,退出运动
						break;
					}
					if(x==0&&y==n-1){     //判断是否为右上角元素,是则执行logo 2操作
						logo=2;
						continue;
					}
				}
			
			if(logo==2){
				x++;
				System.out.print(array[x][y]+" ");

				while(true){		//左下运动
						y--;
						x++;			
					System.out.print(array[x][y]+" ");
					if(x==n-1)		//到达下边界,退出运动
					break;
				}	
				y++;
				System.out.print(array[x][y]+" ");
				if(x==n-1&&y==n-1)    //判断是否达到右下角,达到退出
					break;	
				while(true){		 // 右上运动
						y++;
						x--;			
				System.out.print(array[x][y]+" ");				
					if(y==n-1)      //到达右边界,退出运动
					break;			
				}	
				
			}
			
		  }	
		}		
	}
}



    原文作者:Z字形编排问题
    原文地址: https://blog.csdn.net/for___ever/article/details/83012169
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞