【题目链接】

ybt 1967:【14NOIP普及组】螺旋矩阵
洛谷 P2239 [NOIP2014 普及组] 螺旋矩阵

类似考题:
洛谷 P1014 [NOIP1999 普及组] Cantor 表

【题目考点】

1.二维数组

【解题思路】

记输入的目标位置为(ai, aj)
如果暴力移动焦点,在二位数组中蛇形填写数字,因为数组边长达到30000,数组元素个数为30000∗30000=9∗10830000*30000=9*10^830000∗30000=9∗108,默认计算机1s可以进行小于10810^8108次运算,这样做一定会超时。
每圈的元素个数是容易求的,如果每次移动一圈,到(ai,aj)所在的圈时再一个一个格子移动,这样移动次数就会大大减少。
第1圈边长为n,元素个数为4*(n-1)
第2圈边长为n-2,元素个数为4*(n-2-1)

第i圈边长为n-2*(i-1),元素个数为4*(n-2*(i-1)-1)
每圈边长比上一圈少2,元素个数为4*(边长-1)

第i圈:上面一行的行坐标为:i,下面一行行坐标为:n-i+1,左侧一列列坐标为:i,右侧一列列坐标为n-i+1。
如果目标位置:(ai, aj)的行坐标ai为i或n-i+1,或列坐标aj为i或n-i+1,说明(ai,aj)在第i圈。然后可以有两种方法确定(ai, aj)位置的值。

解法1:移动焦点

第i圈边长为l=n-2*(i-1),将一圈分为等长的四部分,每部分长度为:l-1。焦点从左上角出发,向右移动l-1次后,焦点指向右上角;再向下移动l-1次后,焦点指向右下角;再向左移动l-1次,焦点指向左下角;再向上移动l-1次,完成对第i圈的遍历。
在这一过程中,记录到每个位置时数组元素值。如果遍历到(ai, aj),输出该值。

解法2:坐标计算

记第i圈左上角位置(i,i)的值为st,边长为l。那么右上角(i,n-i+1)的值为:st+l-1,右下角(n-i+1,n-i+1)的值:st+(l-1)*2,左下角(n-i+1,i)的值:st+(l-1)*3。

  • 如果目标位置在第i行,需要从左上角(i,i)移动到(ai,aj)位置,移动aj-i次,值需要加aj-i,那么(ai,aj)位置的值为st+aj-i
  • 如果目标位置在第n-i+1列,需要从右上角(i,n-i+1)移动到(ai,aj)位置,移动ai-i次,那么(ai,aj)位置的值为st+(l-1)+ai-i
  • 如果目标位置在第n-i+1行,需要从右下角(n-i+1,n-i+1)移动到(ai,aj)位置,移动n-i+1-aj次,那么(ai,aj)位置的值为st+2*(l-1)+(n+1-i)-aj
  • 如果目标位置在第i列,需要从左下角(n-i+1,i)移动到(ai,aj)位置,移动n-i+1-ai次,那么(ai,aj)位置的值为st+3*(l-1)+(n+1-i)-ai

【题解代码】

解法1:移动焦点

#include<bits/stdc++.h>
using namespace std;
int main()
{int n, ai, aj, i, st, l;//求(ai,aj)的数 st:该圈起始数字 int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};//右下左上 cin >> n >> ai >> aj;st = 1, l = n;//st:起始数字, l:该圈边长 for(i = 1; i <= n/2; ++i){//看ai,aj是否在第i圈 if(ai == i || ai == n+1-i || aj == i || aj == n+1-i)break;st += 4*l-4;l -= 2;        }//看ai,aj位置是第i圈上第几个格子,求出目标位置的值 int fi = i, fj = i, num = st;//fi,fj:焦点 num:该位置的值  for(int d = 0; d < 4; ++d)//方向 0:右 1:下 2:左 3:上 {int k = 1;do//用do...while是为了当l==1时,也会判断输出解。解决找边长为奇数的二维数组中心位置的问题。 {if(fi == ai && fj == aj)//找到目标位置 {cout << num;return 0;}fi += dir[d][0], fj += dir[d][1];//按照d方向移动到下一个位置 num++;k++;}while(k <= l-1);//每一条边遍历l-1次 }return 0;
}

解法2:坐标计算

#include<bits/stdc++.h>
using namespace std;
int main()
{int n, ai, aj, i, st, l;//求(ai,aj)的数 st:该圈起始数字 cin >> n >> ai >> aj;st = 1, l = n;//st:起始数字, l:该圈边长 for(i = 1; i <= n/2; ++i){//看ai,aj是否在第i层外圈 if(ai == i || ai == n+1-i || aj == i || aj == n+1-i)break;st += 4*l-4;l -= 2;        }if(ai == i)//在第i行cout << st+aj-i;//移动aj-i次else if(aj == n+1-i)//在第n-i+1列cout << st+l-1+ai-i;//移动ai-i次else if(ai == n+1-i)//在第n-i+1行cout << st+2*(l-1)+(n+1-i)-aj;//移动(n+1-i)-aj次else if(aj == i)//在第i列cout << st+3*(l-1)+(n+1-i)-ai;//移动(n+1-i)-ai次return 0;
}

解法3:递归

#include<bits/stdc++.h>
using namespace std;
int getNum(int l, int i, int j)//左上角(1,1)位置的值为1,边长为l的矩阵中(i,j)的值
{if(i == 1)//如果在上边 return j;else if(j == l)//如果在右边 return l-1+i;else if(i == l)//如果在下边 return 2*(l-1)+l-j+1;else if(j == 1)//如果在左边 return 3*(l-1)+l-i+1;else//如果在内部 i,j位置的值为这一圈元素的个数(4*(l-1))加上以(2,2)位置为左上角,以l-2长度为边的矩阵中,(i-1,j-1)位置的值。 return 4*(l-1)+getNum(l-2, i-1, j-1);//以(2,2)位置为左上角时, 原(2,2)变为(1,1),原(i,j)变为(i-1,j-1)
}
int main()
{int n, ai, aj;//求(ai,aj)的数 st:该圈起始数字 cin >> n >> ai >> aj;cout << getNum(n, ai, aj);return 0;
}

信息学奥赛一本通 1967:【14NOIP普及组】螺旋矩阵 | 洛谷 P2239 [NOIP2014 普及组] 螺旋矩阵相关推荐

  1. 信息学奥赛一本通 1392:繁忙的都市(city) | 洛谷 P2330 [SCOI2005]繁忙的都市

    [题目链接] ybt 1392:繁忙的都市(city) 洛谷 P2330 [SCOI2005]繁忙的都市 [题目考点] 1. 图论 最小生成树 [解题思路] 将题目叙述转为图论概念,交叉路口为顶点,道 ...

  2. 信息学奥赛一本通 1375:骑马修栅栏(fence) | 洛谷 P2731 [USACO3.3]骑马修栅栏 Riding the Fences

    [题目链接] ybt 1375:骑马修栅栏(fence) 洛谷 P2731 [USACO3.3]骑马修栅栏 Riding the Fences [题目考点] 1. 图论:欧拉回路 欧拉回路存在的条件: ...

  3. 信息学奥赛一本通 1965:【14NOIP普及组】珠心算测验 | 洛谷 P2141 [NOIP2014 普及组] 珠心算测验

    [题目链接] ybt 1965:[14NOIP普及组]珠心算测验 洛谷 P2141 [NOIP2014 普及组] 珠心算测验 [题目考点] 1. 枚举 [解题思路] 解法1:枚举判断每个数字是否是加和 ...

  4. 信息学奥赛一本通 ybt 1933:【05NOIP普及组】循环 | 洛谷 P1050 [NOIP2005 普及组] 循环

    [题目链接] ybt 1933:[05NOIP普及组]循环 洛谷 P1050 [NOIP2005 普及组] 循环 [题目考点] 1.高精度 2.数学 [解题思路] 要求最后k位的循环长度,可以从低位向 ...

  5. 信息学奥赛一本通 1937:【06NOIP普及组】数列 | 洛谷 P1062 [NOIP2006 普及组] 数列

    [题目链接] ybt 1937:[06NOIP普及组]数列 洛谷 P1062 [NOIP2006 普及组] 数列 [题目考点] 1. 数制 [解题思路] 如果k为2,那么这个数列 第1项为202^02 ...

  6. 信息学奥赛一本通 1961:【13NOIP普及组】计数问题 | 洛谷 P1980 [NOIP2013 普及组] 计数问题

    [题目链接] ybt 1961:[13NOIP普及组]计数问题 洛谷 P1980 [NOIP2013 普及组] 计数问题 [题目考点] 1. 数字拆分 [解题思路] 遍历1~n的各个数字,对每个数字做 ...

  7. 信息学奥赛一本通 1414:【17NOIP普及组】成绩 | 洛谷 P3954 [NOIP2017 普及组] 成绩

    [题目链接] ybt 1414:[17NOIP普及组]成绩 洛谷 P3954 [NOIP2017 普及组] 成绩 [题目考点] 1. 算术表达式 2. 自动类型转换 低精度类型与高精度类型计算结果是高 ...

  8. 信息学奥赛一本通 1924:【03NOIP普及组】栈 | 洛谷 P1044 [NOIP2003 普及组] 栈

    [题目链接] ybt 1924:[03NOIP普及组]栈 洛谷 P1044 [NOIP2003 普及组] 栈 [题目考点] 递推.递归 栈 [解题思路]:一维递推 设数组a,a[i]表示i个数组成的数 ...

  9. 信息学奥赛一本通 1979:【18NOIP普及组】龙虎斗 | 洛谷 P5016 [NOIP2018 普及组] 龙虎斗

    [题目链接] ybt 1979: [18NOIP普及组]龙虎斗 洛谷 P5016 [NOIP2018 普及组] 龙虎斗 [题目考点] 1. long long类型使用 已知变量a, b是int类型的变 ...

最新文章

  1. 单精度和半精度混合训练
  2. UI培训教程分享:UI设计的分类有哪些?
  3. HBase结合MapReduce批量导入
  4. Spring中的事务管理详解
  5. 好好说说Java中的常量池之Class常量池
  6. Java程序员从笨鸟到菜鸟之(四)java开发常用类(包装,数字处理集合等)(上)
  7. iOS 各种系统文件目录 临时,缓存,document,lib,归档,序列化
  8. VS2010中添加lib库引用
  9. 院士袁亚湘:莫把数学当语文来教
  10. android 4.4 keyfactory.getinstance 报错_Android实际开发bug大总结
  11. Nginx基本数据结构之ngx_str_t
  12. 图模型在信息流推荐系统中的原理和实践
  13. 求一个特定函数在定义区间上的值是否都为素数
  14. vscode 转到实现方法失效_动图炫技23个鲜为人知的VS Code快捷键
  15. golang Windows下编译linux可执行文件
  16. 利尔达芯智行智能BMS系统方案,让电池的“大脑”更聪明
  17. office2016安装后右键新建没有word、excel、ppt等解决方法
  18. 一些热门的前端UI组件库(附用例)
  19. ui设计需要会html吗,高逼格UI设计需要从何入手?
  20. GIS开发入坑(一)--GeoServer发布DEM地形图

热门文章

  1. 算法导论——排序算法
  2. dedecns 表结构
  3. HttpNotificationChannel 云端推送信息实现
  4. 盘点8个数据分析相关的Python库(实例+代码)
  5. 一文讲清,MySQL如何解决多事务并发问题
  6. 再有人问你MySql 的隔离级别是什么,就把这篇文章发给他!
  7. 无需付费,教你IDEA社区版中使用Tomcat
  8. 如此沙雕的代码注释,还是程序员会玩!
  9. 漫画:从修灯泡来看各种 IT 岗位,你是哪一种?
  10. docker基础入门和docker compose实战