NOIP 普及组 2014 螺旋矩阵

传送门

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

 

题解:

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

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

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

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

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

  具体细节看代码。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define P pair<int ,int >
 5 
 6 int n,x,y;
 7 P p[5];
 8 bool isSat(){//判断点(x,y)是否在当前四个点所表示的正方框上
 9     //满足其一即可判断在,具体为啥,画个图就明白了
10     if(x == p[1].first || x == p[3].first || y == p[1].second || y == p[2].second)
11         return true;
12     return false;
13 }
14 bool isPos(P _p){//判断当前来到的点是否为所求点(x,y)
15     return x == _p.first && y == _p.second;
16 }
17 int main()
18 {
19     scanf("%d%d%d",&n,&x,&y);
20     //存储四个角的坐标
21     p[1]=P(1,1),p[2]=P(1,n);
22     p[3]=P(n,1),p[4]=P(n,n);
23     while(!isSat())//如果不在当前正方框上,正方框向内缩
24     {
25         p[1].first++,p[1].second++;
26         p[2].first++,p[2].second--;
27         p[3].first--,p[3].second++;
28         p[4].first--,p[4].second--;
29     }
30     ll res=1;
31     for(int i=2;i <= p[1].first;i++)
32         res += 1ll*4*(n-2*i+3);
33     while(p[1].second < p[2].second && !isPos(p[1]))//判断就(x,y)是否在正方框的上边
34         p[1].second++,res++;
35     if(isPos(p[1]))
36     {
37         printf("%lld\n",res);
38         return 0;
39     }
40     
41     while(p[2].first < p[4].first && !isPos(p[2]))//判断就(x,y)是否在正方框的右边
42         p[2].first++,res++;
43     if(isPos(p[2]))
44     {
45         printf("%lld\n",res);
46         return 0;
47     }
48     
49     while(p[4].second > p[3].second && !isPos(p[4]))//判断就(x,y)是否在正方框的下边
50         p[4].second--,res++;
51     if(isPos(p[4]))
52     {
53         printf("%lld\n",res);
54         return 0;
55     }
56     
57     while(!isPos(p[3]))//判断就(x,y)是否在正方框的左边
58         p[3].first--,res++;
59     printf("%lld\n",res);
60 }
View Code

 

posted @ 2018-11-02 22:09  HHHyacinth  阅读(581)  评论(0编辑  收藏  举报