<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        旋轉隊列的簡要分析

        作者:龔平   來源:本站原創   點擊數:  更新時間:2014年03月13日   【字體:

        看到了一道關于旋轉隊列的題目,覺得蠻有意思的,雖然僅僅是一個數值處理問題,但是尋找規律的過程還是蠻有意思的,關于旋轉隊列的實現也已經有了很多的版本,我就其中的一種做簡要的分析和總結。

         
        題目大概如下所示:
        設1點的坐標是(0,0),x方向向右為正,y方向向下為正。例如:7的坐標為(-1,-1),2的坐標為(1,0),3的坐標為(1,1)。編程實現輸入任意一點坐標(x,y),輸出所對應的數字;或輸入任意數字,輸出該數字的坐標。實現的效果如上圖所示,從圖中可知,只需要找到正確的數值分析式,就能夠得到坐標處對應的數值。
         
        下面簡要的分析其中的一些規律,這類問題我覺得關鍵還是要找到突破點,然后找到具體數值的表達式,表達式清楚了就只是程序的轉化問題啦。
         
        從圖上可知,在第0層時只有一個值1,第1層是有8個值(2-9),第2層上的值從10到25,第3層的值從26到49,由圖可知每一層的最后一個值都是奇數的平方(1,9,25,49,81,...),再和層數關聯起來,得到每一層的最后一個數都是(2n+1)^2,同樣每一層的起始值也就可以確定,即(2n-1)^2+1。也就是每一層的值都是處在(2n-1)^2+1和(2n+1)^2之間,這樣采用(2n-1)^2作為一個基準,加上對應的數就能得到具體的數值。
         
        因此我們可以得到如下的結論:
         
        旋轉隊列每一層的開始值都是(2n-1)^2+1,結尾值都是(2n+1)^2,其中的n就是層數(0,1,2,...),可以認為是坐標中較大的絕對值值確定所在的層,比如(2,3),則表示該坐標處于第3層,而(-3,-2)也表示這個數值在第3層上。有了這種層的概念就會使得推理的過程更見的簡單。也就是說坐標值中絕對值較大的值就是所謂的層。
         
        結合上面的圖像可知道,每一層的開始值都是出于東方,也就是x>0的方向,結束于北方,即y<0的方向,這時候我們可以根據東西南北四個方向來確定坐標對應的值。
         
        即:首先采用輸入的坐標值確定該數值對應的層數,然后根據輸入坐標的x,y確定坐標所在的方向,這時候依據每一個方向的起始值就能較好的確定所有的值(具體分析該值與每一層的開始值之間的聯系),但是這種方法有問題,因為每一層上每個方向(東西南北)的起始坐標都是在變化的,并不便于得到通用的表達式。
         
        這時候可以考慮對稱性問題,因為在上面的圖中我們可以知道該圖基本上是按照x,y對稱的,如果我們知道了四個正方向的值,那么就能根據對稱性快速的確定其他的值,也就是只需要知道每一層與坐標軸相交的幾個值就能快速的確定其他的值。
         
        但是如何讓確定坐標軸上的值呢?
         
        這就要密切聯系每一層的結束值(2n+1)^2,根據這個值我們可以知道下一層正東方的值(2n+1)^2+n+1,加入坐標所在的層為K,則正東方的值就應該是(2*K-1)^2+K,這個可以很容易的確定,因為開始值到坐標軸的距離剛好就是層數K,也就是加上K。其他三個方向的值也就能夠快速的確定。
         
        因此我們可以知道每一個方向的對稱軸的表達式分別為:
         
        正東方:(2*K-1)^2+K
        正南方:(2*K-1)^2+3K
        正西方:(2*K-1)^2+5K
        正北方:(2*K-1)^2+7K
         
        依據每一個方向的坐標軸的對稱性確定對應的值,在對稱的方向上只需要一個坐標值就能確定其他的值,這時候四個方向上的值分別為:
         
        東方:(2*K-1)^2 + K + y
        南方:(2*K-1)^2 + 3K - x
        西方:(2*K-1)^2 + 5K - y
        北方:(2*K-1)^2 + 7K + x
         
        這樣也就找到了每一行的表達式,就能實現每一個方向上數值的確定。程序的實現也就相對來說非常容易實現啦。在打印的過程中需要注意數組行列的差別。
         
        實現的基本過程如下:

         

            #include<iostream>
            #include<string>

            using namespace std;

            #define abs(x) ((x) > 0 ? (x) : (-x))
            #define max(x,y) (abs(x) >= abs(y) ? abs(x) : abs(y))

            int reverse_xy(int x, int y)
            {
                    int cnt = 0;

                    /*保存所在的行*/
                    int t = max(x, y);
               
                    /*最先判斷北方(y=-t)*/
                    if(-t == y)
                    {
                            cnt = (2*t-1)*(2*t-1) + 7*t + x;
                    }
                    else if(-t == x)/*西方*/
                    {
                            cnt = (2*t-1)*(2*t-1) + 5*t - y;
                    }
                    else if(t == y)/*南方*/
                    {
                            cnt = (2*t-1)*(2*t-1) + 3*t - x;
                    }
                    else if(t == x)/*東方*/
                    {
                            cnt = (2*t-1)*(2*t-1) + t + y;
                    }

                    return cnt;
            }

            int main()
            {
                    int array[9][9] = {0};

                    int x = 0;
                    int y = 0;

                    for(y = 0; y <= 8 ; ++ y)
                    {
                            for(x = 0; x <= 8; ++ x)
                            {
                                    array[x][y] = reverse_xy(x-4 , y-4);
                                    cout << array[x][y] << "\t";
                            }
                            cout << endl;
                    }
            }

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮