旋轉(zhuǎn)隊(duì)列的簡(jiǎn)要分析
題目大概如下所示:
設(shè)1點(diǎn)的坐標(biāo)是(0,0),x方向向右為正,y方向向下為正。例如:7的坐標(biāo)為(-1,-1),2的坐標(biāo)為(1,0),3的坐標(biāo)為(1,1)。編程實(shí)現(xiàn)輸入任意一點(diǎn)坐標(biāo)(x,y),輸出所對(duì)應(yīng)的數(shù)字;或輸入任意數(shù)字,輸出該數(shù)字的坐標(biāo)。實(shí)現(xiàn)的效果如上圖所示,從圖中可知,只需要找到正確的數(shù)值分析式,就能夠得到坐標(biāo)處對(duì)應(yīng)的數(shù)值。
下面簡(jiǎn)要的分析其中的一些規(guī)律,這類問(wèn)題我覺(jué)得關(guān)鍵還是要找到突破點(diǎn),然后找到具體數(shù)值的表達(dá)式,表達(dá)式清楚了就只是程序的轉(zhuǎn)化問(wèn)題啦。
從圖上可知,在第0層時(shí)只有一個(gè)值1,第1層是有8個(gè)值(2-9),第2層上的值從10到25,第3層的值從26到49,由圖可知每一層的最后一個(gè)值都是奇數(shù)的平方(1,9,25,49,81,...),再和層數(shù)關(guān)聯(lián)起來(lái),得到每一層的最后一個(gè)數(shù)都是(2n+1)^2,同樣每一層的起始值也就可以確定,即(2n-1)^2+1。也就是每一層的值都是處在(2n-1)^2+1和(2n+1)^2之間,這樣采用(2n-1)^2作為一個(gè)基準(zhǔn),加上對(duì)應(yīng)的數(shù)就能得到具體的數(shù)值。
因此我們可以得到如下的結(jié)論:
旋轉(zhuǎn)隊(duì)列每一層的開(kāi)始值都是(2n-1)^2+1,結(jié)尾值都是(2n+1)^2,其中的n就是層數(shù)(0,1,2,...),可以認(rèn)為是坐標(biāo)中較大的絕對(duì)值值確定所在的層,比如(2,3),則表示該坐標(biāo)處于第3層,而(-3,-2)也表示這個(gè)數(shù)值在第3層上。有了這種層的概念就會(huì)使得推理的過(guò)程更見(jiàn)的簡(jiǎn)單。也就是說(shuō)坐標(biāo)值中絕對(duì)值較大的值就是所謂的層。
結(jié)合上面的圖像可知道,每一層的開(kāi)始值都是出于東方,也就是x>0的方向,結(jié)束于北方,即y<0的方向,這時(shí)候我們可以根據(jù)東西南北四個(gè)方向來(lái)確定坐標(biāo)對(duì)應(yīng)的值。
即:首先采用輸入的坐標(biāo)值確定該數(shù)值對(duì)應(yīng)的層數(shù),然后根據(jù)輸入坐標(biāo)的x,y確定坐標(biāo)所在的方向,這時(shí)候依據(jù)每一個(gè)方向的起始值就能較好的確定所有的值(具體分析該值與每一層的開(kāi)始值之間的聯(lián)系),但是這種方法有問(wèn)題,因?yàn)槊恳粚由厦總€(gè)方向(東西南北)的起始坐標(biāo)都是在變化的,并不便于得到通用的表達(dá)式。
這時(shí)候可以考慮對(duì)稱性問(wèn)題,因?yàn)樵谏厦娴膱D中我們可以知道該圖基本上是按照x,y對(duì)稱的,如果我們知道了四個(gè)正方向的值,那么就能根據(jù)對(duì)稱性快速的確定其他的值,也就是只需要知道每一層與坐標(biāo)軸相交的幾個(gè)值就能快速的確定其他的值。
但是如何讓確定坐標(biāo)軸上的值呢?
這就要密切聯(lián)系每一層的結(jié)束值(2n+1)^2,根據(jù)這個(gè)值我們可以知道下一層正東方的值(2n+1)^2+n+1,加入坐標(biāo)所在的層為K,則正東方的值就應(yīng)該是(2*K-1)^2+K,這個(gè)可以很容易的確定,因?yàn)殚_(kāi)始值到坐標(biāo)軸的距離剛好就是層數(shù)K,也就是加上K。其他三個(gè)方向的值也就能夠快速的確定。
因此我們可以知道每一個(gè)方向的對(duì)稱軸的表達(dá)式分別為:
正東方:(2*K-1)^2+K
正南方:(2*K-1)^2+3K
正西方:(2*K-1)^2+5K
正北方:(2*K-1)^2+7K
依據(jù)每一個(gè)方向的坐標(biāo)軸的對(duì)稱性確定對(duì)應(yīng)的值,在對(duì)稱的方向上只需要一個(gè)坐標(biāo)值就能確定其他的值,這時(shí)候四個(gè)方向上的值分別為:
東方:(2*K-1)^2 + K + y
南方:(2*K-1)^2 + 3K - x
西方:(2*K-1)^2 + 5K - y
北方:(2*K-1)^2 + 7K + x
這樣也就找到了每一行的表達(dá)式,就能實(shí)現(xiàn)每一個(gè)方向上數(shù)值的確定。程序的實(shí)現(xiàn)也就相對(duì)來(lái)說(shuō)非常容易實(shí)現(xiàn)啦。在打印的過(guò)程中需要注意數(shù)組行列的差別。
實(shí)現(xiàn)的基本過(guò)程如下:
#include
#include
using namespacestd;
#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] << " ";
}
cout << endl;
}
}
評(píng)論