NOIP 普及组 2014 螺旋矩阵

时间:2023-03-09 06:13:39
NOIP 普及组 2014 螺旋矩阵

传送门

https://www.cnblogs.com/violet-acmer/p/9898636.html

题解:

  这道题挺有意思的,有点考思维吧。

  大体思路是用四个pair<int ,int >变量表示四个角的坐标。

  (1)每次判断所求点( i , j )是否在当前四个点所围城的正方框上。

  (2)如果在,遍历一遍这个框的所有点,输出结果。

  (3)如果不在,四个角往里缩,来到更小的正方框上,重复  (1) 过程

  具体细节看代码。

AC代码:

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define P pair<int ,int > int n,x,y;
P p[];
bool isSat(){//判断点(x,y)是否在当前四个点所表示的正方框上
//满足其一即可判断在,具体为啥,画个图就明白了
if(x == p[].first || x == p[].first || y == p[].second || y == p[].second)
return true;
return false;
}
bool isPos(P _p){//判断当前来到的点是否为所求点(x,y)
return x == _p.first && y == _p.second;
}
int main()
{
scanf("%d%d%d",&n,&x,&y);
//存储四个角的坐标
p[]=P(,),p[]=P(,n);
p[]=P(n,),p[]=P(n,n);
while(!isSat())//如果不在当前正方框上,正方框向内缩
{
p[].first++,p[].second++;
p[].first++,p[].second--;
p[].first--,p[].second++;
p[].first--,p[].second--;
}
ll res=;
for(int i=;i <= p[].first;i++)
res += 1ll**(n-*i+);
while(p[].second < p[].second && !isPos(p[]))//判断就(x,y)是否在正方框的上边
p[].second++,res++;
if(isPos(p[]))
{
printf("%lld\n",res);
return ;
} while(p[].first < p[].first && !isPos(p[]))//判断就(x,y)是否在正方框的右边
p[].first++,res++;
if(isPos(p[]))
{
printf("%lld\n",res);
return ;
} while(p[].second > p[].second && !isPos(p[]))//判断就(x,y)是否在正方框的下边
p[].second--,res++;
if(isPos(p[]))
{
printf("%lld\n",res);
return ;
} while(!isPos(p[]))//判断就(x,y)是否在正方框的左边
p[].first--,res++;
printf("%lld\n",res);
}