- 快速找螺旋矩阵中某个值(part 2)(递归,规律)
- 打出蛇形矩阵(part 1)
南京网赛 发现自己蛇形矩阵都打的不熟练了 QAq>>那就好好加油吧
ヾ(◍°∇°◍)ノ゙(逆时针vision)
#include<bits/stdc++.h>
using namespace std;
int mp[1010][1010];
int main()
{
int n;
while(cin>>n)
{
int tot=n*n;
memset(mp,0,sizeof(mp));
int x=0,y=1;int t=1;
while(t<=tot)
{
while(x+1<=n&&mp[x+1][y]==0)
{
mp[++x][y]=t++;
}
while(y+1<=n&&mp[x][y+1]==0)
{
mp[x][++y]=t++;
}
while(x-1>=1&&mp[x-1][y]==0)
{
mp[--x][y]=t++;
}
while(y-1>=1&&mp[x][y-1]==0)
{
mp[x][--y]=t++;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",mp[i][j]);
}
puts("");
}
}
}
现给出矩阵大小nnn以及iii和jjj,请你求出该矩阵中第iii行第jjj列的数是多少。
(本题目为2014NOIP普及T3)
递归 求出螺旋矩阵对应的值
https://www.luogu.org/problem/P2239
- 思想大概是每次都只处理边界情况然后不断的递归往里面延伸 注意的是每次往里面递进都需要加入这个里面圈左上第一元素左边的值(也就是上一个圈的大小喔)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll work(ll n,ll a,ll b)
{
if(a==1) return b;
if(b==n) return n+a-1;
if(a==n) return 3*n-1-b;
if(b==1) return 4*n-2-a;
return 4*(n-1)+work(n-2,a-1,b-1);
}
int main()
{
ll a,b;
while(~scanf("%lld%lld%lld",&n,&a,&b))
{
printf("%lld\n",work(n,a,b));
}
}
比较高效的求法
解释在下面点~~
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll work(ll n,ll a,ll b)
{
ll q=min(min(a,b),min(n-a+1,n-b+1));
ll ans;
if(a<=b)
{
q--;
ans=4*(n-q)*q+a+b-2*(q+1)+1;
}else //左下的情况
{
ans=4*(n-q)*q-a-b+2*q+1;
}
return ans;
}
int main()
{
ll a,b;
while(~scanf("%lld%lld%lld",&n,&a,&b))
{
printf("%lld\n",work(n,a,b));
}
}
-
首先我们注意到一个规律
某个元素所在的第几个圈和这个元素的坐标有关废话
这个index 就是这个元素到最外面边界的最小距离也就是min(a,b,n-a+1,n-b+1) -
规律二
-
第一个圈的大小 4n-4
-
2 . 4(n-2)-4
-
3 . 4(n-4)-4
-
q. 4(n-2(q-1))-4
-
首先我们讨论圈里的数到这个圈的发起点的距离(包括两个端点)
-
x<=y(右上部分)
如上图20 -17
20 (3,4)
17 (2,2)
距离就是 3+4-2*2+1(所在的是第几个圈)=3+1 -
x>y
-
23(4,2) -17 (左下部分)
-
考虑先补全这个圈在减去(他到第一个点的距离(不包括两个端点),也就是这个数和第一个数之间的插足者了)
-
距离 4+2-2*2-1=2-1=1
-
补全第一,二 个圈4*5-4+4(5-2)-4=24;
-
24-1=23;
每个完整的圈的计算可以套用等差公式啦,