首先当然是找规律
当然厉害的大佬可以直接通过数学方法求解
我这种菜鸡只能打表找找规律
打表就是一个简单的dfs 用一个矩阵记录当前走过的格子 然后朝着一个方向走 要碰到已经走过的格子的时候就换各方向 走过n*n格的时候结束递归,代码如下:
#include<iostream>
#include<cstring>
#include<iomanip>
using namespace std;
int map[108][108];
int ans[108][108];
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
void print(int n){
for(int i=1;i<=n;i++)
{
long long aa=0;
for(int j=1;j<=n;j++)
{
aa+=ans[i][j];
cout<<std::left<<setw(5)<<ans[i][j];
}
cout<<std::left<<setw(10)<<aa;
printf("\n");
}
}
void dfs(int n,int x,int y,int d,int step){
map[x][y]=1;
ans[x][y]=step;
if(step==n*n)
{
print(n);
return ;
}
int dn=(d+1)%4;
int xn=x+dir[dn][0];
int yn=y+dir[dn][1];
if(x+dir[d][0]>n||x+dir[d][1]<1||y+dir[d][1]>n||y+dir[d][1]<1)
dfs(n,xn,yn,dn,step+1);
else if(map[x+dir[d][0]][y+dir[d][1]])
dfs(n,xn,yn,dn,step+1);
else
dfs(n,x+dir[d][0],y+dir[d][1],d,step+1);
}
int main()
{
freopen("test.out","w",stdout);
for(int i=1;i<=100;i++)
{
memset(map,0,sizeof(map));
dfs(i,1,1,0,1);
cout<<endl;
}
}
然后可以根据表很好得出规律 每一行的和的差为一个等差数列
然后分奇偶讨论一下
#include<iostream>
using namespace std;
typedef long long ll;
int main()
{
int n;
scanf("%d",&n);
long long a[n+10];
long long b[n+10];
if(n%2)
{
a[1]=15;
b[1]=3;
for(int i=2;i<n+10;i++) a[i]=1ll*(i-2)*32+46+a[i-1];
for(int i=2;i<n+10;i++) b[i]=1ll*(i-2)*32+30+b[i-1];
long long t=1ll*(n+1)*n/2;
printf("%lld\n",t);
int k=n/2+1;
for(int i=k-1;i>=1;i--)
{
t+=a[i];
printf("%lld\n",t);
}
for(int i=1;i<k;i++)
{
t-=b[i];
printf("%lld\n",t);
}
}
else
{
a[1]=4;
b[1]=14;
for(int i=2;i<n+10;i++) a[i]=1ll*(i-2)*32+30+a[i-1];
for(int i=2;i<n+10;i++) b[i]=1ll*(i-2)*32+46+b[i-1];
long long t=1ll*(n+1)*n/2;
printf("%lld\n",t);
int k=n/2;
for(int i=k;i>=1;i--)
{
t+=a[i];
printf("%lld\n",t);
}
for(int i=1;i<k;i++)
{
t-=b[i];
printf("%lld\n",t);
}
}
}