题目: 矩阵中填数. 当给出 N*N 的矩阵,要求用程序填入下列形式的数:例如N=5
① 倒填 ② 蛇形填数 ③ 回转填数
25 24 23 22 21 1 3 4 10 11 1 16 15 14 13
20 19 18 17 16 2 5 9 12 19 2 17 24 23 12
15 14 13 12 11 6 8 13 18 20 3 18 25 22 11
10 9 8 7 6 7 14 17 21 24 4 19 20 21 10
5 4 3 2 1 15 16 22 23 25 5 6 7 8 9
解答:
第一种很简单,在打印的时候控制从大到小就可以了。
第二种,在打印的时候就不是很好办了,那么就先把数存在一个二维数组里面。
算法:
0.把1填在第一个位置
1.如果当前位置右上角可以填数,则把下一个数放在右上角,到1,不能则把数放在它的右边,
如果右边不能放,则放在下面,到2。
2.如果当前位置左下角可以填数,则把下一个数放在左下脚,到2,不能则把数放在它的下面,
如果下面不能放,则放在右边,到1。
在最外层加控制条件(所有数放完)
第三种和第二种方法相似,也是沿着指定的方式放数,到不能放时转换方向。
#include < cstring >
using namespace std;
void BackFill( int );
void SnakeFill( int );
void GyrationFill( int );
int main(){
cout << " Input the size number: " ;
int n;
cin >> n;
BackFill(n);
SnakeFill(n);
GyrationFill(n);
}
void BackFill( int n){
cout << " BackFill Number: " ;
for ( int i = 0 ;i < n;i ++ ){
for ( int j = 0 ;j < n;j ++ )
cout << n * n - j - i * n << " " ;
cout << endl;
}
}
void SnakeFill( int n){
int ** a = new int * [n];
for ( int i = 0 ;i < n;i ++ )
a[i] = new int [n];
int count = 2 ,i = 1 ,j = 0 ;
a[ 0 ][ 0 ] = 1 ;
while (count <= n * n){
while (i >= 0 && j < n){
a[i][j] = count ++ ;
i -- ;
j ++ ;
}
if (j >= n)
j -- ,i ++ ;
i ++ ;
while (j >= 0 && i < n)
{
a[i][j] = count ++ ;
i ++ ;
j -- ;
}
if (i >= n)
i -- ,j ++ ;
j ++ ;
}
cout << " SnakeFill Number: " ;
for ( int i = 0 ;i < n;i ++ ){
for ( int j = 0 ;j < n;j ++ )
cout << a[i][j] << " " ;
cout << endl;
}
for ( int i = 0 ;i < n;i ++ )
delete[] a[i];
delete[] a;
}
void GyrationFill( int n){
int ** a = new int * [n];
for ( int i = 0 ;i < n;i ++ ){
a[i] = new int [n];
memset(a[i], 0 ,n * sizeof ( int ));
}
int count = 1 ,i = 0 ,j = 0 ;
while (count <= n * n){
while (i < n && a[i][j] == 0 ){
a[i][j] = count ++ ;
i ++ ;
}
i -- ,j ++ ;
while (j < n && a[i][j] == 0 ){
a[i][j] = count ++ ;
j ++ ;
}
j -- ,i -- ;
while (i >= 0 && a[i][j] == 0 ){
a[i][j] = count ++ ;
i -- ;
}
i ++ ,j -- ;
while (j >= 0 && a[i][j] == 0 ){
a[i][j] = count ++ ;
j -- ;
}
j ++ ,i ++ ;
}
cout << " GyrationFill Number: " ;
for ( int i = 0 ;i < n;i ++ ){
for ( int j = 0 ;j < n;j ++ )
cout << a[i][j] << " " ;
cout << endl;
}
for ( int i = 0 ;i < n;i ++ )
delete[] a[i];
delete[] a;
}
最后这个题还有一个需要注意的地方,就是我们开的二维数组大小要在运行的时候才能确定,所以只能开在堆区,在C++里面在堆区分配内存用的是运算符new,它返回它操作数类型的指针。但是它不能直接开两个维数都不确定的二维数组,我上面写的是一种开二维数组的方法。另外在我们用完了数组后,一定要记得清理内存,在C++里用运算符delete,对于清理数组用delete[] ,如果忘了写最后几行代码,就是C++里最常见的内存泄露问题。