1 // 一道有趣的面试题.cpp : 定义控制台应用程序的入口点。 2 3 /************************************************* 4 设计者:cslave 5 版本说明:本代码免费用于商用,拷贝,转移,使用,但是 6 有本代码导致的问题,本人概不负责。 7 设计时间:2012.7.10 8 分发原则:遵守GNU规范。 9 **************************************************/ 10 /************************************************** 11 12 题目:输入n 求一个n*n的矩阵,规定矩阵沿45度角线递增, 13 形成一个zigzag数组,请问如何用C++实现 14 如图: 15 16 Please Input The Number! 17 8 18 0 1 5 6 14 15 27 28 19 2 4 7 13 16 26 29 42 20 3 8 12 17 25 30 41 43 21 9 11 18 24 31 40 44 53 22 10 19 23 32 39 45 52 54 23 20 22 33 38 46 51 55 60 24 21 34 37 47 50 56 59 61 25 35 36 48 49 57 58 62 63 26 27 28 分析: 29 先看矩阵,发现矩阵对角线上部元素与下部对应元素之和为N^2-1 30 即为 Arr[i][j]+Arr[N-1-i][N-1-j]=N^2-1 31 32 所以我们只需要处理上三角即可,下三角可推出。 33 观察上三角中。 34 数组各项横纵坐标与值的关系 35 0 0 0 36 0 1 1 37 1 0 2 38 2 0 3 39 1 1 4 40 0 2 5 41 0 3 6 42 1 2 7 43 2 1 8 44 3 0 9 45 4 0 10 46 从中分析 发现(i+j)的和与结果有关系 47 令 s=i+j 48 s=0 只有0 1个元素落在这个范围 49 s=1 有2个 50 s=2 有3个 51 s=3 有4个 52 s=4 。。。 53 这样 54 任意一项Arr[i][j],令s=i+j 55 则该项之前的s-1项有 56 1+2+...+s=s(s+1)/2这么多个数,那么该数位于哪个位置? 57 我们再看看 添加其前s-1项的和 58 0 0 0 0 59 0 1 1 1 60 1 0 2 1 61 2 0 3 3 62 1 1 4 3 63 0 2 5 3 64 0 3 6 6 65 1 2 7 6 66 2 1 8 6 67 3 0 9 6 68 4 0 10 10 69 从中我们可以看出 ,当s能够被2整除时 Arr[i][j]=s(s+1)/2+j 70 否则 Arr[i][j]=s(s+1)/2+i; 71 72 ****************************************************/ 73 74 75 76 #include "stdafx.h" 77 #include <iostream> 78 #include <iomanip> 79 using namespace std; 80 81 int _tmain(int argc, _TCHAR* argv[]) 82 { 83 int N; 84 int s,i,j; 85 cout<<"Please Input The Number!"<<endl; 86 cin>>N; 87 int** Arr=new int*[N];//int** Arr=(int **)malloc(N*sizeof(int)); 88 for(i=0;i<N;i++) 89 Arr[i]=new int[N];//Arr[i]=(int*)malloc(N*sizeof(int));严格来讲这里应该加强防错处理。 90 for(i=0;i<N;i++) 91 for(j=0;j<N-i;j++) 92 { 93 s=i+j; 94 if(s<N) 95 { 96 Arr[i][j]=s*(s+1)/2+((s%2==0)? j:i); 97 } 98 } 99 for(i=N-1;i>0;i--) 100 for(j=N-i;j<N;j++) 101 { 102 Arr[i][j]=N*N-1-Arr[N-1-i][N-1-j]; 103 } 104 for(i=0;i<N;i++) 105 { 106 for(j=0;j<N;j++) 107 cout<<setw(6)<<Arr[i][j]; 108 cout<<endl; 109 } 110 return 0; 111 }