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

 

转载于:https://www.cnblogs.com/violet-acmer/p/9898753.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值