题目描述
思路

我想到的第一种思路是开一个二维数组,螺旋填入数字,按照坐标输出对应位置的元素。但当n非常大的时候,无法开出相应的二维数组。然后就想到模拟螺旋填数过程,用两个变量x,y存当前填数的格子的坐标。当x=i,y=j的时候,输出当前要填的数。
如果一个格子一个格子的去填数字一定会超时,而且在一条直线上直到转弯前需要填的格子数目是可以通过计算得出的。只要在转弯处判断目标格子是否在当前要填的直线段上,在的话就用已经填的格子数目加上目标格子相应坐标与当前直线段的端点坐标的差,否则加上当前直线段所有要填的格子数目,然后转弯。

代码[c++]
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int main() {
int n;
scanf("%d",&n);
int x,y;
scanf("%d%d",&x,&y);
int xx=1,yy=1;
long long int ans = 1;
int a=n,b=n,c=1,d=1;//相当于划定边界
if(n%2==1&&(n+1)/2==x&&(n+1)/2==y)//特判n为奇数且求中心格子
ans=n*n;
else {
while(1) {
if(xx==x&&y>=yy&&y<a) {
ans+=(y-yy);
break;
} else {
ans+=(a-yy);
yy=a;
}
a--;
if(yy==y&&x>=xx&&x<b) {
ans+=(x-xx);
break;
} else {
ans+=(b-xx);
xx=b;
}
b--;
if(xx==x&&y<=yy&&y>c) {
ans+=(yy-y);
break;
} else {
ans+=(yy-c);
yy=c;
}
c++;
if(yy==y&&x<=xx&&x>d) {
ans+=(xx-x);
break;
} else {
ans+=(xx-d);
xx=d+1;
yy=c;
}
d++;
}
}
printf("%lld\n",ans);
return 0;
}
05-11 16:21