面試題-螺旋矩陣(模擬)

     最近無聊的很,看了看一些基礎的面試題,雖說簡單點,但還是能學到一點東西的。
就比方main函數結束之後還能執行函數嗎?答案是可以,使用atexit註冊一個函數就可以了。
下面重點談談這個螺旋矩陣!
關於螺旋矩陣的說法不一,這裏指的是形如
           21  22................
           20  7  8  9  10
           19  6  1  2  11
           18  5  4  3  12
           17  16 15 14 13
的矩陣。

問題有兩個:
1. 編程實現輸出這個矩陣
2. 設1點的座標是(0,0),x方向向右爲正,y方向向下爲正.例如:7的座標爲(-1,-1) ,2的座標爲(0,1),3的座標爲(1,1).編程實現輸入任意一點座標(x,y),輸出所對應的數字。

1. 第一個問題我是採用模擬進行構造的,可以看到從1開始的方向變化始終是 right->down->left->up,
所持續走的長度爲1->1->2->2->3->3->...,發現了這個規律不難寫出代碼了!注意下面我把1的位置設置
在((n-1)/2, (n-1)/2)的位置。

void Simulate(int n)
{
    
int x, y;
    x 
= y = (n - 1/ 2//1的位置
    data[x][y] = 1;
    
int len = 1;
    
int count = 0;
    
int num = 2;
    DIRECTION dir 
= RIGHT;
    
while(num  <= n * n)
    
{
        
for(int i = 0; i < len; i++)
        
{
            
switch(dir)
            
{
            
case LEFT:
                
--y;    break;
            
case RIGHT:
                
++y;     break;
            
case UP:
                
--x;    break;
            
case DOWN:
                
++x;    break;
            
default:    break;
            }

            data[x][y] 
= num++;
        }

        count
++;
        
if(count == 2)
        
{
            count 
= 0;
            len
++;    
        }

        dir 
= (DIRECTION)((dir + 1% 4);
    }

}

2. 第二個問題我也是先找出規律,然後進行模擬。
首先,不難看出n*n的螺旋矩陣的右下角的座標一定是(m, m),這裏m=n-1
通過觀察,可以看出 n=1的時候,右下角(0,0)的值爲1,當n=2的時候,右下角(1,1)的座標值爲(3,3),當n=3的時候,右下角(2,2)的座標值爲13.直覺告訴我,這個值是關於n的二次函數,設f(n) = a*n^2 + b*n + c
聯立方程組,可以求得a,b,c。 最終算出來的f(n) = 4*n^2 - 2*n + 1
下面再根據(x,y)和右下角(n-1,n-1)之間的關係,計算出值即可。這裏要注意當x的值與n-1相同時,應優先考慮y與-m是否有聯繫。這就要求在函數中要注意x,y的判斷先後順序了。
代碼如下:
//以(1,1)所在位置作爲原點,向右作爲x正半軸,向下作爲y正半軸
int GetValue(int x, int y)
{
    
int m = max(abs(x), abs(y));
    
int rightBottom = m * m * 4 - 2 * m + 1;
    
int value = 0;
    
if(x == -m)
    
{
        value 
= rightBottom + 2 * m + m - y;
    }

    
else if( y == m)
    
{
        value 
= rightBottom + m - x;
    }

    
else if(y == -m)
    
{
        value 
= rightBottom + 4 * m + x + m;
    }

    
else if( x == m )
    
{
        value 
= rightBottom - (m - y);
    }

    

    
return value;
}



完整代碼如下:

#include <iostream>
#include 
<cstdlib>
#include 
<algorithm>

using namespace std;

const int N = 100;

int data[N + 1][N + 1];

enum DIRECTION
{
    RIGHT, DOWN , LEFT, UP
};

//模擬整個過程
void Simulate(int n)
{
    
int x, y;
    x 
= y = (n - 1/ 2//1的位置
    data[x][y] = 1;
    
int len = 1;
    
int count = 0;
    
int num = 2;
    DIRECTION dir 
= RIGHT;
    
while(num  <= n * n)
    {
        
for(int i = 0; i < len; i++)
        {
            
switch(dir)
            {
            
case LEFT:
                
--y;    break;
            
case RIGHT:
                
++y;     break;
            
case UP:
                
--x;    break;
            
case DOWN:
                
++x;    break;
            
default:    break;
            }
            data[x][y] 
= num++;
        }
        count
++;
        
if(count == 2)
        {
            count 
= 0;
            len
++;    
        }
        dir 
= (DIRECTION)((dir + 1% 4);
    }
}

//打印螺旋矩陣
void Output(int n)
{
    
int i, j;
    
for(i = 0; i < n; i++)
    {
        cout 
<< data[i][0];
        
for(j = 1; j < n; j++)
            cout 
<< "\t" << data[i][j];
        cout 
<< endl;
    }
}

//以(1,1)所在位置作爲原點,向右作爲x正半軸,向下作爲y正半軸
int GetValue(int x, int y)
{
    
int m = max(abs(x), abs(y));
    
int rightBottom = m * m * 4 - 2 * m + 1;
    
int value = 0;
    
if(x == -m)
    {
        value 
= rightBottom + 2 * m + m - y;
    }
    
else if( y == m)
    {
        value 
= rightBottom + m - x;
    }
    
else if(y == -m)
    {
        value 
= rightBottom + 4 * m + x + m;
    }
    
else if( x == m )
    {
        value 
= rightBottom - (m - y);
    }
    

    
return value;
}

void TestPos(int n)
{
    
int i, j;
    
for(i = 0; i < n; i++)
    {
        cout 
<< GetValue(0 - (n - 1/ 2, i - (n - 1/ 2);
        
for(j = 1; j < n; j++)
            cout 
<< "\t" << GetValue(j - (n - 1/ 2, i - (n - 1/ 2);
        cout 
<< endl;
    }
}

int main()
{
    
int n;
    
while(cin >> n)
    {
        
if(n <= 0 || n > 100)
        {
            cerr 
<< "Size error!" << endl;
            
break;
        }
        
else
        {
            Simulate(n);
            Output(n);
            cout 
<< "*******************" << endl;
            TestPos(n);
        }
    }

    
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章