题目传送门
思路一看就是构造题,显然要分成若干块 5 × 5 5times5 5×5 的小块,然后发现对于一个小块中,只有最中间的那格可以从别的小块中一步跳进来。
然后我们打一个爆搜,打出从当前小块的中间走到各个方向相邻的小块的方案。
这样就可以在小块间移动了。
由于我们需要把所有的点都绕一遍,那么显然是在 2 ∼ N 5 2sim frac{N}{5} 2∼5N 行上边绕来绕去,直到最后一列绕完之后从第一行绕回第一格。
所以在 N N N 为奇数的时候,最后上去的时候需要把两列一起处理掉,然后就爆搜跑一个 5 × 10 5times10 5×10 绕一遍的解(从 ( 3 , 3 ) (3,3) (3,3) 开始走最后走到 ( 3 , 1 ) (3,1) (3,1)),然后输出即可,注意特判 N = 5 N=5 N=5 和 N = 15 N=15 N=15 的点。
代码#includeusing namespace std; int n; int st[11][11]={ { 1,13,16, 0,12}, { 9, 4,23,20, 7}, {15,18,11,14,17}, { 2,21, 8, 3,22}, {10, 5,24,19, 6}, }; int ed[11][11]={ {21,15, 5,20,14}, {10,18,23,11, 3}, {25, 7, 1,16, 6}, {22,12, 4,19,13}, { 9,17,24, 8, 2}, }; int corner[11][11]={ {28,41,50,27,42,18,24, 5,17,10}, {38,21,30,39,13,46,32,12,45, 7}, {49,35, 1,19,34,26,43, 9,25, 4}, {29,40,14,22,31,15,23, 6,16,11}, {37,20,48,36, 2,47,33, 3,44, 8}, }; int down[11][11]={ {18,13, 5,19,14}, {10,21,16,11, 3}, {24, 7, 1,23, 6}, {17,12, 4,20,15}, { 9,22,25, 8, 2}, }; int r[11][11]={ {10,16, 5,11,17}, {21,13, 8,20, 3}, { 6,24, 1,15,25}, { 9,19, 4,12,18}, {22,14, 7,23, 2}, }; int up[11][11]={ {18,10,25,17,11}, { 5,21,13, 8, 3}, {24,16, 1,23,15}, {19, 9, 4,20,12}, { 6,22,14, 7, 2}, }; int l[11][11]={ {21,15, 5,20,14}, {10,18,23,11, 3}, {25, 7, 1,16, 6}, {22,12, 4,19,13}, { 9,17,24, 8, 2}, }; int tmp[11][11]={ {19,45,40,18,46,41,15, 5,30,10}, {38,22,48,43,13,26,32,12,27, 7}, {50,35, 1,24,34,17,29, 9,16, 4}, {20,44,39,21,47,42,14, 6,31,11}, {37,23,49,36, 2,25,33, 3,28, 8}, }; int ans[5001][5001]; void copy(int x,int y,const int (*a)[11],int n,int m,int st){ for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)ans[(x-1)*5+i][(y-1)*5+j]=a[i-1][j-1]+st-1; } int main(){ cin>>n; if(n%10==0){ copy(1,1,st,5,5,1);ans[1][4]=n*n; int m=n/5,now=25; for(int i=1;i<=m;i++){ if(i&1){ for(int j=2;j for(int j=m;j>2;j--)copy(j,i,up,5,5,now),now+=25; copy(2,i,r,5,5,now);now+=25; } else{ for(int j=m;j>1;j--)copy(j,i,up,5,5,now),now+=25; } } for(int i=m;i>2;i--)copy(1,i,l,5,5,now),now+=25; copy(1,2,ed,5,5,now);now+=25; } else if(n==5){ puts("1 14 7 4 15n 9 22 17 12 23n 19 5 25 20 6n 2 13 8 3 16n 10 21 18 11 24"); return 0; } else{ copy(1,1,st,5,5,1);ans[1][4]=n*n; int m=n/5,now=25; for(int i=1;i if(i&1){ for(int j=2;j for(int j=m;j>2;j--)copy(j,i,up,5,5,now),now+=25; copy(2,i,r,5,5,now);now+=25; } else{ for(int j=m;j>1;j--)copy(j,i,up,5,5,now),now+=25; } } for(int i=m;i>=2;i--)copy(i,m-1,corner,5,10,now),now+=50; copy(1,m-1,tmp,5,10,now),now+=50; for(int i=m-2;i>2;i--)copy(1,i,l,5,5,now),now+=25; if(m>3)copy(1,2,ed,5,5,now);now+=25; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ printf("%d%c",ans[i][j],"n "[j 有问题请指出,谢谢–zhengjun


![洛谷 P6291 [eJOI2017]骆驼 题解--zhengjun 洛谷 P6291 [eJOI2017]骆驼 题解--zhengjun](http://www.mshxw.com/aiimages/31/948212.png)
