| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 【NOIP2014】普及组题目详解 -> 正文阅读 |
|
[数据结构与算法]【NOIP2014】普及组题目详解 |
本次NOIP普及共4道题,其实挺水的,本人在12:00-13:30切掉前三题,在晚上花了1个小时把最后一题切掉,现奉上详解。 T1 珠心算测验题意:随机生成一个正整数集合,集合中的数各不相同,回答:其中有多少个数,恰好等于集合中另外两个(不同的)数之和? 但是这个题坑点在 1 + 2 1+2 1+2和 2 + 1 2+1 2+1只能算一个(初中、小学的可能不知道集合是什么意思,简单来说就是一些元素的整合,其中的性质有一条非常关键,则是“不可重复”) 我们考虑再开一个数组,记录一下这个数有没有被算过就行了,这题其实理想的状态是拿到就能切掉的,2分钟读题,3分钟写完,二等奖到手。 C o d e Code Code:
T2 比例简化题意:给定三个数 A , B , L A,B,L A,B,L,将 A : B A:B A:B化简为 A ’ : B ’ A’:B’ A’:B’,要求在 A ’ A’ A’和 B ’ B’ B’均不大于 L L L且 A ’ A’ A’和 B ’ B’ B’互质(两个整数的最大公约数是 1 1 1)的前提下, A ’ / B ’ ≥ A / B A’/B’≥ A/B A’/B’≥A/B且 A ’ / B ’ ? A / B A’/B’- A/B A’/B’?A/B的值尽可能小。 样例:in:1498 902 10 详解:跟T1相比,这道题是个纯纯的思维题。 题解有人写 g c d gcd gcd,但是这个题可以不用写,我们需要枚举 T 2 T^2 T2中的数,开一个 t m p tmp tmp把 i / j i/j i/j的数记录下来,做 T 2 T^2 T2次和 a / b a/b a/b的比较,如果大于等于,就求差,再找最小值。然后将 i , j i,j i,j替换到 x , y x,y x,y就行了。(这一步也可以放在比较前,是等价的,思考一下为什么。) 注意,因为枚举 i / j i/j i/j,所以所有的数都要开成 d o u b l e double double类型的! C o d e Code Code:
T3 螺旋矩阵题意:一个“蛇形方阵”,给出
T
T
T,输出一个
T
?
T
T*T
T?T的类似于下图的矩阵
给出 i , j i,j i,j,查找 a ( i , j ) a(i,j) a(i,j)的值输出。 详解: 不行,这题开二维肯定是过不了的! 我们先来看看 50 p t s 50pts 50pts的做法,其实就是 O ( n ) O(n) O(n)模拟出蛇形方阵,(关于蛇形方阵的解法,其实就是跟一条蛇一样,T=奇数和T=偶数时不一样,如果是奇数那么在方阵中间填上 n ? n n*n n?n就行了,具体看代码)。然后 O ( 1 ) O(1) O(1)把 ( x , y ) (x,y) (x,y)跑出来就行了。 C o d e ( 50 p t s ) Code(50pts) Code(50pts):
这样会爆内存。 考虑100pts的做法。 好像没什么能优化的了,只能找规律了! 手画出 6 x 6 6x6 6x6的方阵。 把螺旋矩阵一层一层拆开,看看目标位置在哪一层,然后加上这一层最左上角的数字 ( 4 × ( n ? 1 ) ) (4×(n?1)) (4×(n?1)),即为要求的数字。 观察它们具有以下性质: 1.如果是第
1
1
1行,那么第
j
j
j列的数字就是
j
j
j; 那么得出这四条性质,那么我们就可以爆搜搜出答案了!
T4 子矩阵题目太长,甩个链接。 详解:毒瘤至极的DP! 暴力能得50pts,不过我觉得暴力的想法跟正解差不多。 我们要设 f [ j ] [ k ] f[j][k] f[j][k]表示当前选了 j j j个数,且强制选择第 k k k个数的最小分值。 然后我们枚举在第 k k k个数之前选或不选第 i i i个数 易得方程 f [ j ] [ k ] = m i n ( f [ j ] [ k ] , f [ j ? 1 ] [ i ] + f 2 [ i ] [ k ] ) ; f[j][k]=min(f[j][k],f[j-1][i]+f2[i][k]); f[j][k]=min(f[j][k],f[j?1][i]+f2[i][k]); 其中 f 2 [ i ] [ k ] f2[i][k] f2[i][k]表示 i , k i,k i,k之间的差。 现在把一个数变成一列中的几个数,但我们不知道是哪几个数 那么就从 n n n行中暴力搜索选出 c c c行,与列相交的地方便是要选的数 现在我们有一个c*m的矩阵,也就是把序列中的数变成了c个数 我们要考虑列与列之间的分值和行与行之间的分值 因为行已经确定,则设 h [ i ] h[i] h[i]为第 i i i列中相邻数间的分值 由于列不确定选哪些,设 f [ i ] [ k ] f[i][k] f[i][k]为任意两列之间的分值 则 f [ j ] [ k ] = m i n ( f [ j ] [ k ] , f [ j ? 1 ] [ i ] + h [ k ] + f 2 [ i ] [ j ] ) ; f[j][k]=min(f[j][k],f[j-1][i]+h[k]+f2[i][j]); f[j][k]=min(f[j][k],f[j?1][i]+h[k]+f2[i][j]); h [ k ] h[k] h[k]为选择第k列在行与行之间产生的分值 d p [ 1 ] [ k ] = h [ k ] dp[1][k]=h[k] dp[1][k]=h[k],即只产生行之间的分值 因为行数不超过16,我在枚举中用一个数代替判重数组
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/9 1:57:28- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |