乙個n行n列的螺旋矩陣可由如下方法生成:
從矩陣的左上角(第1行第1列)出發,初始時向右移動;如果前方是未曾經過的格仔,則繼續前進,否則右轉;重複上述操作直至經過矩陣中所有格仔。
根據經過順序,在格仔中依次填入1,2
,3,…
,n21,2,3,…,n^2
1,2,3,
…,n2
,便構成了乙個螺旋矩陣。
下圖是乙個n = 4 時的螺旋矩陣。
現給出矩陣大小n以及i和j,請你求出該矩陣中第i行第j列的數是多少。
輸入格式
輸入共一行,包含三個整數 n,i,j,每兩個整數之間用乙個空格隔開,分別表示矩陣大小、待求的數所在的行號和列號。
輸出格式
輸出共一行,包含乙個整數,表示相應矩陣中第i行第j列的數。
資料範圍
1 ≤n
≤30000
1≤n≤30000
1≤n≤30
000,
1 ≤i
,j≤n
1≤i,j≤n
1≤i,j≤
n輸入樣例:
4 2 3輸出樣例: 注意題目中給出的資料範圍,1≤n
≤30000
1≤n≤30000
1≤n≤30
000,使用二維陣列進行模擬的話會爆空間。考慮要求矩陣中第x
行第y
列的數,可以像剝洋蔥一樣,一層層地把矩陣剝開。只要確定x
和y
在矩陣的哪一層,就可以快速地計算出其所對應的值。
在矩陣中,可以通過位置(x,
y)(x,y)
(x,y
)的上下左右偏移量的最小值確定其所在層,例如下圖中第4行2列的數23,top = 3, down = 2, left = 2, right = 4
,其最小之為2
,所以它位於矩陣的第二層。
找到( x,
y)(x,y)
(x,y
)所在層後,可以使用迴圈計算出其所在層左上角的位置(r,c)
和該位置對應的數ans
,以及該層所在矩陣的大小n
。例如第4行2列的數23,其所在層的左上角的位置 是(2,
2)(2,2)
(2,2
),對應的數為ans
=1+4
×(5−
1)=17
ans=1 + 4 \times (5 - 1)=17
ans=1+
4×(5
−1)=
17,子矩陣的大小為n=5
−2=3
n = 5 - 2 = 3
n=5−2=
3。其中1
11為起點對應的數,除了起點第一行有(5−
1)(5-1)
(5−1
)個數、第5列有(5−
1)(5-1)
(5−1
)個數、第5行有(5−
1)(5-1)
(5−1
)個數、第1列有(5−
1)(5-1)
(5−1
)個數。
同理,其它層也可以這麼計算。
計算出位置(x,
y)(x,y)
(x,y
)所在矩陣左上角的位置(r,
c)(r,c)
(r,c
),和該位置對應的數字ans
,以及該層矩陣的大小n
,可以通過判斷位置(x,
y)(x,y)
(x,y
)的位置,快速計算出該位置對應的數:
時間複雜度o(n
)o(n)
o(n)
,空間複雜度o(1
)o(1)
o(1)
。
#include
using
namespace std;
intmain()
if(x == r) ans +
= y - c;
//如果在該層的第一行上
//如果在該層的最後一列
else
if(y == c + n -
1) ans +
= n -
1+ x - r;
//如果在該層的最後一行
else
if(x == r + n -
1) ans +=3
* n -3-
(y - c)
;//如果在該層的第一列
else ans +=4
* n -4-
(x - r)
;
cout << ans << endl;
return0;
}
noip 2017 普及組 T3 棋盤
有乙個m m的棋盤,棋盤上每乙個格仔可能是紅色 黃色或沒有任何顏色的。你現在要從棋盤的最左上角走到棋盤的最右下角。任何乙個時刻,你所站在的位置必須是有顏色的 不能是無色的 你只能向上 下 左 右四個方向前進。當你從乙個格仔走向另乙個格仔時,如果兩個格仔的顏色相同,那你不需要花費金幣 如果不同,則你需...
NOIP2014 普及組 螺旋矩陣
一 題目 noip2014 普及組 螺旋矩陣 時間限制 1 sec 記憶體限制 128 mb 提交 18 解決 0 提交 狀態 討論版 題目描述 乙個n行n列的螺旋矩陣可由如下方法生成 從矩陣的左上角 第1行第1列 出發,初始時向右移動 如果前方是未曾經過的格仔,則繼續前進,否則右轉 重複上述操作直...
NOIP2014普及組 子矩陣
給出如下定義 1.子矩陣 從乙個矩陣當中選取某些行和某些列交叉位置所組成的新矩陣 保持行與列的相對順序 被稱為原矩陣的乙個子矩陣。例如,下面左圖中選取第 2 4 行和第 2 4 5 列交叉位置的元素得到乙個 2 x 3 的子矩陣如右圖所示。93 3399 4874 1746 6685 6974 56...