咱們都熟悉走馬步,如今咱們定義一種新的移動方式——駱駝步,它在一個國際棋盤上的移動規則是這樣的。c++
以看出,駱駝步能夠向八個方向走動,且不能走出棋盤範圍。
如今給出一個$N\times N$的棋盤,其中$N$是$5$的倍數。你須要從左上角出發,每步按照駱駝步的規則,通過每一個格子剛好一次,且當你走了$N^2-1$步後,你離起點剛好只有一步的距離。
請給出一種合法的方案。spa
第一行有一個整數$N$,表示$N\times N$的棋盤blog
若是無解,輸出$"impossible"$
不然,你輸出一個$N\times N$的矩陣,其中$a_{i,j}$表示$(i,j)$是你通過的第$a_{i,j}$個格子。it
樣例輸入:class
10im
樣例輸出:數據
1 52 29 8 51 28 9 50 37 16
85 95 59 86 94 66 87 93 65 88
40 19 100 39 18 76 38 17 77 49
2 53 30 7 58 27 10 89 36 15
84 96 60 75 99 67 72 92 64 71
41 20 82 44 23 90 45 24 78 48
3 54 31 6 57 26 11 68 35 14
83 97 61 74 98 62 73 91 63 70
42 21 81 43 22 80 46 25 79 47
4 55 32 5 56 33 12 69 34 13db
對於全部數據,保證$N\leqslant 1,000$且$N$是$5$的倍數。
其中一個數據點$N=5$,佔$20$分,剩餘$16$個數據點,每一個$5$分。img
$N$是$5$的倍數無形中提示着咱們不可能有$"impossible"$的數據點。移動
其中一個數據點$N=5$又提示着咱們從這裏入手。
事實證實,在一個$5\times 5$的格子裏,從一個格子出發能終點能夠是任意一個格子,那麼能夠考慮先預處理出來一些$5\times 5$的走法,而後拼接起來。
那麼這時候分爲兩種狀況:
$\alpha.N$是奇數。
$\beta.N$是偶數。
對於狀況$\alpha$有這樣一個構造方案:
上圖中白點爲總的起點,灰點表示每個$5\times 5$的格子的起點,藍點表示終點,黃點和紅點分別表示最後兩步。
對於狀況$\beta$有這樣一個構造方案:
上圖中白點爲總的起點,灰點表示每個$5\times 5$的格子的起點,藍點表示終點,紅點表示最後一步。
這樣爲題就簡單多了,咱們須要預處理七種$5\times 5$的格子,而後按照如上方案構造便可。
注意$N=5$須要特判
時間複雜度:$\Theta(n^2)$。
指望得分:$100$分。
實際得分:$100$分。
#include<bits/stdc++.h>
using namespace std;
int n;
int Map[1001][1001],t;
int base1[6][6]={0,0,0,0,0,0,0,1,6,11,-1,5,0,9,15,3,8,16,0,12,21,18,13,22,0,2,7,10,-1,4,0,19,14,23,20,17};
int base2[6][6]={0,0,0,0,0,0,0,10,21,6,9,22,0,16,13,24,19,14,0,5,8,1,4,7,0,11,20,15,12,23,0,17,3,25,18,2};
int base3[6][6]={0,0,0,0,0,0,0,18,10,24,17,9,0,13,21,7,12,22,0,5,16,1,4,25,0,19,11,23,20,8,0,14,3,6,15,2};
int base4[6][6]={0,0,0,0,0,0,0,21,10,25,22,9,0,15,18,7,12,17,0,5,23,1,4,24,0,20,11,16,19,8,0,14,3,6,13,2};
int base5[6][6]={0,0,0,0,0,0,0,18,5,24,19,6,0,10,21,16,9,22,0,25,13,1,4,14,0,17,8,23,20,7,0,11,3,15,12,2};
int base6[6][6]={0,0,0,0,0,0,0,25,17,7,24,16,0,12,4,21,13,5,0,19,9,1,18,8,0,22,14,6,23,15,0,11,3,20,10,2};
int base7[6][6]={0,0,0,0,0,0,0,1,6,13,21,5,0,11,19,3,8,18,0,14,22,-1,15,23,0,2,7,12,20,4,0,10,16,24,9,17};
void up(int x,int y)
{
x--;y--;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
Map[x*5+i][y*5+j]=base4[i][j]+t;
t+=25;
}
void down(int x,int y)
{
x--;y--;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
Map[x*5+i][y*5+j]=base2[i][j]+t;
t+=25;
}
void right(int x,int y)
{
x--;y--;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
Map[x*5+i][y*5+j]=base3[i][j]+t;
t+=25;
}
void left(int x,int y)
{
x--;y--;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
Map[x*5+i][y*5+j]=base5[i][j]+t;
t+=25;
}
void work1()
{
t=23;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
Map[i][j]=base1[i][j];
Map[4][4]=n*n-1;
Map[1][4]=n*n;
for(int i=2;i<n/5;i++)down(i,1);
right(n/5,1);
for(int i=n/5;i>2;i--)
{
if(i&1)
{
for(int j=2;j<n/5;j++)right(i,j);
up(i,n/5);
}
else
{
for(int j=n/5;j>2;j--)left(i,j);
up(i,2);
}
}
for(int i=n/5;i>2;i--)
{
if(i&1)
{
up(2,i);
left(1,i);
}
else
{
down(1,i);
left(2,i);
}
}
down(1,2);
for(int i=6;i<=10;i++)
for(int j=6;j<=10;j++)
Map[i][j]=base6[i-5][j-5]+t;
}
void work2()
{
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
Map[i][j]=base7[i][j];
Map[3][3]=n*n;t=24;
for(int i=2;i<n/5;i++)down(i,1);
right(n/5,1);
for(int i=n/5;i>=2;i--)
{
for(int j=2;j<n/5;j++)right(i,j);
up(i,n/5);
i--;
for(int j=n/5;j>=3;j--)left(i,j);
up(i,2);
}
t-=25;left(1,2);
}
int main()
{
scanf("%d",&n);
if(n==5){puts("1 9 19 2 10\n14 22 5 13 21\n7 17 25 8 18\n4 12 20 3 11\n15 23 6 16 24");return 0;}
if(n&1)work1();
else work2();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
printf("%d ",Map[i][j]);
puts("");
}
return 0;
}
rp++