EOJ 3536. 蛇形矩阵

首先当然是找规律

当然厉害的大佬可以直接通过数学方法求解

我这种菜鸡只能打表找找规律

打表就是一个简单的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);
		}
	}	
	
} 

猜你喜欢

转载自blog.csdn.net/zyw764662004/article/details/81410728