洛谷 P2239 [NOIP2014 普及组] 螺旋矩阵

本文由Jzwalliser原创,发布在CSDN平台上,遵循CC 4.0 BY-SA协议。
因此,若需转载/引用本文,请注明作者并附原文链接,且禁止删除/修改本段文字。
违者必究,谢谢配合。
个人主页:blog.csdn.net/jzwalliser

题目

洛谷 P2239 [NOIP2014 普及组] 螺旋矩阵

[NOIP2014 普及组] 螺旋矩阵

题目背景

NOIP2014 普及组 T3

题目描述

一个 n n n 行 $ n$ 列的螺旋矩阵可由如下方法生成:

从矩阵的左上角(第 1 1 1 行第 1 1 1 列)出发,初始时向右移动;如果前方是未曾经过的格子,则继续前进,否则右转;重复上述操作直至经过矩阵中所有格子。根据经过顺序,在格子中依次填入 1 , 2 , 3 , … , n 2 1, 2, 3, \dots, n^2 1,2,3,,n2,便构成了一个螺旋矩阵。

下图是一个 n = 4 n = 4 n=4 时的螺旋矩阵。

( 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 ) \begin{pmatrix} 1 & 2 & 3 & 4 \\ 12 & 13 & 14 & 5 \\ 11 & 16 & 15 & 6 \\ 10 & 9 & 8 & 7 \\ \end{pmatrix} 11211102131693141584567

现给出矩阵大小 n n n 以及 i i i j j j,请你求出该矩阵中第 i i i 行第 j j j 列的数是多少。

输入格式

共一行,包含三个整数 n n n, i i i, j j j,每两个整数之间用一个空格隔开,分别表示矩阵大小、待求的数所在的行号和列号。

输出格式

一个整数,表示相应矩阵中第 i i i 行第 j j j 列的数。

样例 #1

样例输入 #1
4 2 3
样例输出 #1
14

提示

【数据说明】

对于 50 % 50\% 50% 的数据, 1 ⩽ n ⩽ 100 1 \leqslant n \leqslant 100 1n100;

对于 100 % 100\% 100% 的数据, 1 ⩽ n ⩽ 30 , 000 , 1 ⩽ i ⩽ n , 1 ⩽ j ⩽ n 1 \leqslant n \leqslant 30,000,1 \leqslant i \leqslant n,1 \leqslant j \leqslant n 1n30,000,1in,1jn

想法

这道题用枚举的方法当然是可以的,但只能那50分,因为枚举的时间复杂度为 O ( n 2 ) O(n^2) O(n2),对于 n = 30000 n=30000 n=30000来说是不现实的。下面我们讨论更高效的算法。以一个较为简单的矩阵 ( n = 8 ) (n=8) (n=8)为例:
能否从中找出嵌套关系呢?我们会发现,从最边缘到中心,可以像这样划分:

在这里插入图片描述

这里,每种颜色代表一层,每一层的结构都是一样的:从左上角开始,绕一圈回来。

那么,下一步就比较明确了:给定坐标(j,i),能否确定坐标在第几层呢?

又是找规律:以第二层(蓝色)为例,这些点是在第二层内的: ( 2 , 2 ∼ 7 ) (2,2\sim7) (2,27) ( 2 ∼ 7 , 2 ) (2\sim7,2) (27,2) ( 7 , 2 ∼ 7 ) (7,2\sim7) (7,27) ( 2 ∼ 7 , 7 ) (2\sim7,7) (27,7)。总结一下,对于任意坐标 ( j , i ) (j,i) (j,i),它在第 k = min ⁡ { i , j , ( n + i − 1 ) , ( n + j − 1 ) } k=\min\{i,j,(n+i-1),(n+j-1)\} k=min{i,j,(n+i1),(n+j1)}层( min ⁡ { a , b , c , d } \min\{a,b,c,d\} min{a,b,c,d}代表 a a a b b b c c c d d d中的最小值, n n n为矩阵边长)。

现在,我们只需知道第 k k k层的第一个数是几,然后根据坐标向后顺移若干个数。如: ( 6 , 2 ) (6,2) (6,2)在第 2 2 2层,第 2 2 2层的第 1 1 1个数是 29 29 29 ( 6 , 2 ) (6,2) (6,2)是第 2 2 2层的第 5 5 5个数,所以向后顺移 4 4 4个数。故坐标 ( 6 , 2 ) (6,2) (6,2)代表的数为 25 + 9 − 1 = 33 25+9-1=33 25+91=33

先解决第一个问题:求第 k k k层的第 1 1 1个数 s k s_k sk为几。这可以用面积法求解,如下图:

在这里插入图片描述

S 绿 = S 总 − S 红 = n 2 − ( n − 2 m ) 2 S_绿=S_总-S_红=n^2-(n-2m)^2 S绿=SS=n2(n2m)2
比如对于第 2 2 2层来说, s 2 = 8 2 − 6 2 + 1 = 29 s_2=8^2-6^2+1=29 s2=8262+1=29。意思是,第 1 1 1层可容纳 8 2 − 6 2 = 28 8^2-6^2=28 8262=28个数字。因此第 2 2 2层的第 1 1 1个数为 s 2 = 28 + 1 = 29 s_2=28+1=29 s2=28+1=29

故可得:
s k = n 2 − [ n − 2 ( k − 1 ) ] 2 + 1 = n 2 − [ n 2 − 4 n ( k − 1 ) + 4 ( k − 1 ) 2 ] + 1 = 4 n ( k − 1 ) − 4 ( k − 1 ) 2 + 1 = [ 4 n − 4 ( k − 1 ) ] ( k − 1 ) + 1 = 4 ( n − k + 1 ) ( k − 1 ) + 1 \begin{aligned} s_k&=n^2-[n-2(k-1)]^2+1\\&=n^2-[n^2-4n(k-1)+4(k-1)^2]+1\\&=4n(k-1)-4(k-1)^2+1\\&=[4n-4(k-1)](k-1)+1\\&=4(n-k+1)(k-1)+1 \end{aligned} sk=n2[n2(k1)]2+1=n2[n24n(k1)+4(k1)2]+1=4n(k1)4(k1)2+1=[4n4(k1)](k1)+1=4(nk+1)(k1)+1

现在到了第二个问题:该向后顺移几位呢?这回就没有非常简洁的公式了,我们只能分类讨论。
在区域①:向后顺移 ( j − k ) (j-k) (jk)
在区域②:先向后顺移掉整个区域①,再顺移 ( i − k ) (i-k) (ik)
在区域③:先向后顺移掉整个区域①②,再“反向顺移” ( j − k ) (j-k) (jk)
在区域④:先向后顺移掉整个区域①②③ ,再“反向顺移” ( i − k ) (i-k) (ik)

归纳为数学公式,假设坐标 ( j , i ) (j,i) (j,i)的数为 x x x,则:

区域①: i = k i=k i=k时, x = s + j − k x=s+j-k x=s+jk
区域②: j = n + 1 − k j=n+1-k j=n+1k时, x = s + [ n − 2 ( k − 1 ) ] − 1 + i − k = s + n − 3 k + 1 + i x=s+[n-2(k-1)]-1+i-k=s+n-3k+1+i x=s+[n2(k1)]1+ik=s+n3k+1+i
区域③: i = n + 1 − k i=n+1-k i=n+1k时, x = s + 2 [ n − 2 ( k − 1 ) ] − 2 + ( n + 1 − k − j ) = s + 3 n − 5 k + 3 − j x=s+2[n-2(k-1)]-2+(n+1-k-j)=s+3n-5k+3-j x=s+2[n2(k1)]2+(n+1kj)=s+3n5k+3j
区域④: j = k j=k j=k时, x = s + 3 [ n − 2 ( k − 1 ) ] − 3 + ( n + 1 − k − i ) = s + 3 n − 5 k + 3 − j x=s+3[n-2(k-1)]-3+(n+1-k-i)=s+3n-5k+3-j x=s+3[n2(k1)]3+(n+1ki)=s+3n5k+3j

(后面的区域均排除之前的区域)
最后,我们按照刚才推出的公式即可设计程序,时间复杂度 O ( 1 ) O(1) O(1),效率可谓是非常高啊。

实现

  1. 输入
  2. 代入刚才的公式进行计算。
  3. 输出。

题解

C++

#include<bits/stdc++.h>
using namespace std;
int main(){int n,i,j;cin >> n >> i >> j; //输入int k = min(min(min(i,j),n + 1 - i),n + 1 - j); //算出kint s = 4 * (n - k + 1) * (k - 1) + 1; //算出sif(i == k){cout << s + j - k;return 0;}if(j == n + 1 - k){cout << s + n - 3 * k + 1 + i;return 0;}if(i == n + 1 - k){cout << s + 3 * n - 5 * k + 3 - j;return 0;}if(j == k){cout << s + 4 * n - 7 * k + 4 - i;return 0;}
}

Python

n,i,j = input().split() #输入
n = int(n)
i = int(i)
j = int(j)
k = min([i,j,n + 1 - i,n + 1 - j]) #算出k
s = 4 * (n - k + 1) * (k - 1) + 1 #算出s
if i == k:print(s + j - k)raise SystemExitif j == n + 1 - k:print(s + n - 3 * k + 1 + i)raise SystemExitif i == n + 1 - k:print(s + 3 * n - 5 * k + 3 - j)raise SystemExitif j == k:print(s + 4 * n - 7 * k + 4 - i)raise SystemExit

难度

难度:★★★☆☆
这题还是挺难的,至少数学公式的推导可谓是非常费尽,需要思考很长时间。

结尾

这道题你是怎么让AC的?欢迎讨论₍˄·͈༝·͈˄*₎◞ ̑̑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/10323.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

python通过usb连接标签打印机-开源的

背景&#xff1a; 最近接到了一个新需求&#xff0c;单位想做一个ERP系统&#xff0c;想把打印机一起兼容进去&#xff0c;实现自动化打印工作。主要我是做爬虫的没接触过这些&#xff0c;就到网上搜索了很多先关资料&#xff0c;最终发现&#xff0c;一大堆全都是什么VIP的才能…

Codeforces Round 984 (Div. 3)

题目链接 A. Quintomania 题意 思路 模拟即可 示例代码 void solve() {int n;cin >> n;vector<int>arr(n);fer(i, 0 ,n) cin >> arr[i];fer(i, 1, n){if(abs(arr[i] - arr[i - 1]) ! 5 && abs(arr[i] - arr[i - 1]) ! 7){cout << "N…

【2】GD32H7xx 串口Idle + DMA接收不定长数据

目录 1. IDLE中断相关介绍2. D-Cache与DMA同时使用2.1 I-Cache与D-Cache2.2 D-Cache与DMA同时使用时的数据一致性问题2.2.1 CPU读取DMA写入到SRAM的数据2.2.2 DMA读取CPU写入到SRAM的数据 3. Uart Idle DMA收发程序4. 程序测试 1. IDLE中断相关介绍 在 GD32H7xx MCU 中&#…

python数据结构基础(8)

今天来使用python实现二叉树,二叉树中每个节点都是Node类对象,通过Tree类中的add()方法逐个向二叉树中加入树节点,构成完全二叉树或者非完全二叉树,代码如下: class Node(object):"""树节点类&#xff0c;用于构建二叉树。Attributes:- val: 节点存储的值。- r…

IEEE 1588:电信网络的精确时间协议 (PTP)

IEEE 1588&#xff1a;电信网络的精确时间协议 IEEE 1588 PTP 概述PTP 协议特征同步类型IEEE 1588 PTP 角色IEEE 1588 PTP 的工作原理PTP 设备类型PTP 消息类型事件消息一般信息 PTP 时钟类规范PTP 配置文件 https://www.techplayon.com/ieee-1588-precision-time-protocol-ptp…

深度学习基础—了解词嵌入

引言 上图是使用one-hot向量表示词向量的一种方式&#xff0c;这种表示方式优点是方面简洁&#xff0c;但是缺点也很明显&#xff0c;就是词与词之间独立性太强&#xff0c;没有关联&#xff0c;这样使得算法对相关词的泛化能力不强。 举个例子&#xff0c;假如我们已经学习到了…

实战:索引的命中机制

在 SQL Server 中,查询是否能命中索引(即是否能使用 Index Seek)取决于多个因素,包括索引的结构、查询条件的排列、和数据库优化器的策略。以下是一些常见的命中索引和不能命中索引的情况,及其详细解释: 一、命中索引的情况 1. 前导列匹配(典型的命中索引场景) 索引结…

Mac 安装protobuf2.5.0

文章目录 一、修改platform_macros.h二、编译protobuf三、配置环境变量四、测试 一、修改platform_macros.h platform_macros.h的目录位置为/Users/xxxx/protobuf-2.5.0/src/google/protobuf/stubs 在platform_macros.h中增加如下代码 #elif defined(__arm64__) #define GOOG…

ubuntu24.04安装matlab失败

又是摸鱼摆烂的一天&#xff0c;好难过&#xff5e; 官方教程&#xff1a;https://ww2.mathworks.cn/help/install/ug/install-products-with-internet-connection.html 问题描述&#xff1a;https://ww2.mathworks.cn/matlabcentral/answers/2158925-cannot-install-matlab-r2…

python使用turtle画图快速入门,轻松完成作业练习

turtle介绍 turtle是一个绘图库&#xff0c;可以通过编程进行绘图。其模拟了一个乌龟在屏幕上的运动过程。该库通常用于给青少年学习编程&#xff0c;当然&#xff0c;也可以使用其进行作图。 在一些学校中&#xff0c;可能在python学习的课程中&#xff0c;要求完成turtle绘…

智能 AI 视觉识别系统打造高效流量统计方案

智能AI视觉算法解决方案&#xff0c;涵盖客流人数统计、车流量统计、牲畜养殖场计数、物品点包计数、超员报警、火焰识别报警及驾驶行为报警等功能。可精准统计商场、车站等地客流&#xff0c;区分车型统计车流量并预警拥堵&#xff0c;准确计数牲畜及物品&#xff0c;检测工厂…

UVa514 解析:火车车厢重排序问题的模拟栈实现

来源:UVa514 铁轨 Rails。 这是一个火车车厢重排序的问题,通过模拟栈操作的算法实现。这种算法非常适用于具有栈结构特性的问题,比如括号匹配、货物堆放、编译器中语法检查。本文给出了C++的两种代码实现和Python的一种实现。 题目描述 某城市有一个火车站,铁轨铺设如图。…

ENSP OSPF和BGP引入

路由协议分为&#xff1a;内部网关协议和外部网关协议。内部网关协议用于自治系统内部的路由&#xff0c;包括&#xff1a;RIP和OSPF。外部网关协议用于自治系统之间的路由&#xff0c;包括BGP。内部网关协议和外部网关协议配合来共同完成网络的路由。 BGP:边界网关路由协议(b…

华为OD机试真题-矩形绘制

题目描述 实现一个简单的绘图模块&#xff0c;绘图模块仅支持矩形的绘制和擦除 当新绘制的矩形与之前的图形重善时&#xff0c;对图形取并集 当新擦除的矩形与之前的图形重善时&#xff0c;对图形取差集 给定一系列矩形的绘制和擦除操作&#xff0c;计算最终图形的面积。下…

Android下的系统调用 (syscall),内联汇编syscall

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 什么是系统调用 (syscall) 系统调用是操作系统提供给应用程序的一组接口&#xff0c;允许用户空间程序与内核进行交互。 在 Android&#xff08;基于 Linux …

初始JavaEE篇 —— 网络编程(2):了解套接字,从0到1实现回显服务器

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 TCP 与 UDP Socket套接字 UDP TCP 网络基础知识 在一篇文章中&#xff0c;我们了解了基础的网络知识&#xff0c;网络的出…

【月之暗面kimi-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

架构师备考-概念背诵(软件工程)

软件工程 软件开发生命周期: 软件定义时期:包括可行性研究和详细需求分析过程,任务是确定软件开发工程必须完成的总目标,具体可分成问题定义、可行性研究、需求分析等。软件开发时期:就是软件的设计与实现,可分成概要设计、详细设计、编码、测试等。软件运行和维护:就是…

[FBCTF 2019]rceservice 详细题解

知识点: json字符串 PHP正则表达式元字符 PCRE回溯机制绕过正则表达式 %0a 换行符绕过正则表达式(详细讲解) 提示 Enter command as JSON 题目还有一个附件,打开是index.php文件源码 <?php putenv(PATH/home/rceservice/jail); if (isset($_REQUEST[cmd])) {$json $_…

【竞技宝】DOTA2-梦幻联赛S24:圣剑美杜莎强拆基地终结比赛

北京时间11月9日,DOTA2的梦幻联赛S24继续进行。本日迎来第二阶段的B组二、三名加赛PARI对阵spirit。本场比赛双方前两局战至1-1平,决胜局同样是难分胜负打到了六十分钟之后,关键时刻spirit主动出击,圣剑美杜莎强拆基地成功一波结束比赛,最终spirit让一追二击败PARI。以下是本场…