初赛历年真题

2008

1.Sybase是一种数据库
2.控制器的基本功能是控制机器各个部件协调工作
3.计算子串的个数用公式(n+n+1)/2 +1不过记住全不子串,记得要减去空子串
4.在一个二叉树中,度为1的节点要么为1要么为0,如果n为奇数说明度为1的节点为0,那么,因为n0=n2+1,n=2n0+1,所以n=2(n2+1)-1所以通过换算就能求出来n2然后通过公式计算n0
5.可以手(jiao)动模拟一下,也可以将序列排序后和原序列进行比较
6.模拟过程,比较出最小的元素即可
7.小数转进制
8.常识问题
9.常识问题,看见路由器就选网络
10.将二分画成解答树,平均比较次数=查找次数和/总个数
11.2000年中国姚期智获得图灵奖
12.常识问题
13.常识问题,注意优先级,非>与>或
14.Flickr是Web应用的绝佳例子
15.常识问题
16.根据选项,前序中序建树然后比较后序序列,一个一个试
17.面向过程程序设计是自顶向下的
18.树,连通无环,n-1条边
19.常识问题
20.防火墙是一项协助确保信息安全的设备,可能是一套软件,还是一种数据包过滤器,防火墙是在应用层工作
21.先建图,然后用Dijkstra跑一遍,通常都是用dij,因为这个算法好操作好实现
22.n个元素中选m个元素,两两不相邻的方案C(n-m+1,m);不过也可以理解成从18个空位中插入4个
23.O(1)模拟
24.简单递归,直接模拟
25.三位数的全排列,数据不大,可以直接模拟
26.简单的模拟,没有干啥的,没有固定的关系
27.找第k大的数,用寻找中转数的方法来解决
类似于快速排序,i和j表示两个哨兵,然后不断通过随机数作为基准数来转移
28.简单的模拟,循环求出的就是满足题目的k的性质,循环结束了说明答案就能知道了

2009

1.图灵机是图灵提出来的一种思想
2.常识问题
3.将j的ASCLL的码转化成16进制即可
4.常识问题,补码转成原码然后转成十进制即可
5.注意读题,先用log取出总节点个数,然后利用n=2n0+1即可求,这里的n是除去叶子节点的个数,注意读题
6.常识问题,通过中缀转化成树然后跑一下后序遍历
7.Huffman编码不允许一个编码是另一个的前缀
8.快速排序的平均速度是O(nlogn),最快情况退化成冒泡,O(n2)
9.prim算法类似于dij算法,从起点开始选取直接到达中最小的依次加入,起点也要算入
10.常识问题,noi.cn,cn表示国家的
11.Intel最早开发的软件是微处理器,比较位数的时候,不能比较谁快
12.这个题就是计算机的常识问题,高速缓冲并不算什么,RAM的作用也不是这个
13.电脑CPU只有一个,操作系统有的是收费的
14.IP6是IP4的升级,IP5不存在;网络协议分层不是为了兼容,而是根据网络分层模型
15.HTML没有实现统一编码,本网站可以通过超链接实现
16.根据邻接矩阵建图,然后依次比较选项即可
17.clist指向的是链表的最后一个元素,next指向每一个元素的下一个节点,两个指针的意义不同;至于循环链表就是指首尾相连的链表,形成一个环状,比如之前我们接触的玩具谜题就是如此
18.这一个题想了很长时间,很重要,这个题变态的地方在于,枚举不同的情况,意思就是,发生冲突后,这个数可能在这个位置吗
19.希尔,快速,选择,堆都是不稳定的
20.常识问题,手工计算叫做打表…
21.这里求得是拓扑排序个数,我们知道,拓扑排序不确定得原因在于只要满足某个点在某个点的前面即可,所以,这就是利用排列组合的原理解决的
22.on no~,我貌似并不会这个题啊,对于这些数学题,我很没有信心;其实,看第一眼我就感觉是跟进制有关系
23.欧几里得算法,常识
24.直接进行模拟,如果太懒,可以带入小的数推导大的数
25.计算杨辉三角和的程序,这里涉及到二项式的定理,二项式定理是根据完全平方公式来转化的
26.将分数转化成小数,第一个for循环的p是用来标识循环节,k是用来记录循环节,然后通过类似于按位处理的方式(高精度的经典)
27.通过最后输出的两个东西我们可以判定ans代表和,len代表子序列的长度,那么beg的意义通过len=i-beg就能理解了;第2个空就是用来尝试能否尽量地将长度变大;第三四个空就是用来判断这个和为负数的情况下,需要舍去当前的解,所以将beg取下一个数的前一个所以为i;如果为整数,就保留这个数
综合,考虑三种情况,更新答案,更新长度,和为负数情况
28.emmmmmm
这个28题似乎很难,因为…
首先先从main函数开始,hash数组目前有点像桶进行存储,maxnum比较出最大的,我们发现并没有work函数的事情,所以6肯定填和work相关的,因为我们求得是0~59,所以第6个是从0开始
确定这个,我们还得看看work函数是干什么的,看见1是从空的位置跳过
因为我们要枚举枚举公差,所以公差的最大范围就是second-first,
因为我们不能让解无限的大大大大大,所以我们只能让ans-1
ok是用来标记是否能组成等差数列,所以第5空就能求了
delta是用来表示项数的数据
二项式定理

2010

1.进制常识问题
2.字节和位的换算常识问题
3.逻辑常识问题,注意优先级,注意当PQ不给值得情况下,枚举四种情况,恒为就是都是真的情况
4.Linux没有拓展名
5.先看7×7在十进制下是49,然后一句49和41之间用短除的关系确定进制,算出结果
6.计算机常识问题,存储程序原理是冯诺依曼
7.用栈从后往前扫一遍
8.高速缓冲是用来提高时间效率的
9.计算父亲的值,二叉树的常识问题
10.竞赛常识,NOI的时间最悠久
11.因为是多选题,无非就是枚举一下
12.高级语言又分了自然语言和解释语言两个种类
13.排序常识问题,桶需要开的辅助空间和数据规模有关
14.对于这种题,用手算即可
15.根据两个序列,确定左子树根节点,右子树根节点,这样就能确定左子树的节点个数
16.<a href “网址”> 内容 < /a >的形如才是一个超链接
17.有向无环图才能使用拓扑排序,孤点的情况使得入度为0的点也可以在入度非0的后面
18.平面几何知识,平面方程为3x+2y+z=6,只有D满足
19.链表的基本操作,常识,考虑矛盾,是否最后链能连上
20.这么冷的题也考,ccf没题了吗
21.直接模拟
22.这个题其实就是一个类似于排列组合的问题,需要单个进行分析,很重要
23.维护前缀和,将所有可能为9的集合列出来,然后利用鸽巢原理,不能包含两个或者两个以上的,得出答案
24.可以直接模拟,求在序列中那些数,那些数之前有m个数不比他大,比较绕口,对于这种只输出一个数的题,可以推导
25.归并排序 ,可直接模拟
26.直接模拟,递归可以用画表的方式,也可以推式子
27.深度遍历图,并求出字典序最小的序列,很明显用swap来遍历,然后单开一个函数判断 字典序最小的
28.月黑风高的夜晚,这个题好熟悉啊,这个题就是1007的那个独木桥的题吧
pos记录这个人是从左到右还是从右到左,stage记录当前的状态,其实接下来的路程就是穷举的过程
12是一套,23是一套,
1表示只有1个人或者2个人的时候直接过河
2表示深度搜索下去,
3表示穷举左岸的人
4再次进行回溯
5表示存储答案
29.貌似是动态规划?
用动态规划加上堆的操作,题目已经给出来了
堆的插入和删除很简单都是模板,但是5和6操作比较难想,要想让距离最小,所以让距离每次加上堆顶的值,比较变态

2011

1.进制问题,很常识
2.将Z转成64进制即可
3.遍历问题常识
4.寄存器是CPU的组成部分
5.搜索常识问题
6.空间是指,程序运行时理论上所占的内存空间
7.最好的情况,每次不用往下进行查找,每次的时间会往下缩小一半
8.万维网联盟(W3C)是实现涉及HTML、XML、CSS的机构
9.一个一个比较然后插入进去,常识问题,将待排序的序列逐个插入到有序序列
10.历史常识问题,三个人共同发明半导体
11.这个题如果用正常的公式算的话,会得到12,那么还有一种情况,就是除了根节点这一层有一个之外,其他的的每一层

<think>我们正在处理的问题是:优化Java代码解决子数组和等于k的问题。 原代码采用双重循环,时间复杂度为$O(n^2)$,在数据量较大时效率较低。 根据引用[1]和引用[2]中提供的代码,我们可以使用前缀和和哈希表来优化,将时间复杂度降低到$O(n)$。 优化思路: 1. 使用一个变量`prefixSum`来记录从数组开头到当前元素的前缀和。 2. 使用一个哈希表`map`来存储各个前缀和出现的次数。 3. 遍历数组,对于每个元素,更新当前的前缀和`prefixSum`。 4. 在遍历过程中,我们检查哈希表中是否存在前缀和为`prefixSum - k`的项。如果存在,说明存在一个子数组(从之前某个位置到当前位置)的和为`k`,因此将对应的次数累加到计数器中。 5. 更新哈希表中当前前缀和出现的次数。 注意:初始化时,我们需要将前缀和为0的次数置为1,因为当`prefixSum == k`时,`prefixSum - k = 0`,表示从数组开头到当前位置的子数组和恰好为k。 优化后的代码(参考引用[1]和[2]): ```java import java.util.HashMap; import java.util.Map; public class Solution { public int subarraySum(int[] nums, int k) { int count = 0; // 计数器 int prefixSum = 0; // 前缀和 Map<Integer, Integer> map = new HashMap<>(); // 初始化:前缀和为0出现1次 map.put(0, 1); for (int num : nums) { prefixSum += num; // 如果存在前缀和为prefixSum - k,则说明存在子数组和为k if (map.containsKey(prefixSum - k)) { count += map.get(prefixSum - k); } // 更新当前前缀和出现的次数 map.put(prefixSum, map.getOrDefault(prefixSum, 0) + 1); } return count; } } ``` 复杂度分析: - 时间复杂度:$O(n)$,其中$n$是数组的长度。我们只需要遍历一次数组。 - 空间复杂度:$O(n)$,哈希表在最坏情况下需要存储$n$个不同的前缀和。 优化点: 1. 原代码的双重循环被优化为单次遍历,大大提高了效率。 2. 利用了前缀和的思想,通过存储前缀和的出现次数,避免了重复计算。 然而,需要注意的是,这种方法的空间复杂度为$O(n)$,因为使用了额外的哈希表。在数组长度非常大时,可能会占用较多内存,但通常时间效率的提升更为重要。 另外,引用[3]和[4]的内容与当前问题关联不大,引用[3]是关于斐波那契数列的跳台阶问题,引用[4]是关于最长无重复字符子串的滑动窗口算法,因此我们没有采用。 如果数组中的元素存在负数,这个优化方法仍然有效,因为前缀和加上负数可能使得同一个前缀和值出现多次,因此我们需要用哈希表记录每个前缀和出现的次数。 相关问题: 1. 如果数组中存在负数,是否会影响该优化算法的正确性? 2. 是否有进一步优化空间复杂度的方法? 3. 这种方法是否可以扩展到解决子数组和的其他问题,比如子数组和的绝对值等于k? </think>### 优化分析:子数组和等于k的问题 #### 原始代码分析 ```java public class Solution { public int subarraySum(int[] nums, int k) { int count = 0; for (int start = 0; start < nums.length; ++start) { int sum = 0; for (int end = start; end >= 0; --end) { sum += nums[end]; if (sum == k) count++; } } return count; } } ``` - **时间复杂度**:$O(n^2)$(双重循环) - **空间复杂度**:$O(1)$ - **问题**:当数组长度较大时效率极低(如$n=10^5$需计算约$5 \times 10^9$次) #### 优化方案:前缀和+哈希表 参考引用[1][2],使用前缀和与哈希表实现$O(n)$解法: ```java import java.util.HashMap; import java.util.Map; public class Solution { public int subarraySum(int[] nums, int k) { int count = 0, prefixSum = 0; Map<Integer, Integer> map = new HashMap<>(); map.put(0, 1); // 初始化:前缀和为0出现1次 for (int num : nums) { prefixSum += num; // 计算当前前缀和 // 检查是否存在满足条件的前缀和 if (map.containsKey(prefixSum - k)) { count += map.get(prefixSum - k); } // 更新当前前缀和出现次数 map.put(prefixSum, map.getOrDefault(prefixSum, 0) + 1); } return count; } } ``` #### 优化原理 1. **前缀和定义**: - 设$prefixSum[i] = \sum_{j=0}^{i} nums[j]$ - 子数组和$sum(i,j) = prefixSum[j] - prefixSum[i-1]$ 2. **核心等式**: - 当$prefixSum[j] - prefixSum[i] = k$时,说明子数组$[i+1,j]$和为$k$[^1] - 相当于在哈希表中查找$prefixSum[j] - k$ 3. **哈希表作用**: - `key`:前缀和的值 - `value`:该前缀和出现的次数 - 初始化`put(0,1)`处理$prefixSum[j] = k$的情况 #### 复杂度分析 - **时间复杂度**:$O(n)$(单次遍历) - **空间复杂度**:$O(n)$(哈希表存储前缀和) #### 进一步优化点 1. **负数处理**: - 哈希表可正确处理包含负数的数组(原始解法无此限制) 2. **边界优化**: - 若$k$值极大且数组元素较小,可跳过无效迭代,但最坏复杂度不变 3. **并行计算**(大数据场景): ```java // 使用Java Stream API并行处理(适用于大型数组) Arrays.parallelPrefix(nums, Integer::sum); // 并行计算前缀和 ``` 4. **内存优化**: - 对于严格非负数组,可使用双指针滑动窗口($O(n)$时间,$O(1)$空间)[^4] --- ### 相关问题 1. **如何修改算法处理子数组和绝对值等于k的问题?** (需考虑负数和零的特殊情况) 2. **当数组元素全为非负数时,是否有更优的空间优化方案?** (滑动窗口法能否应用?限制条件是什么?) 3. **如何处理多维数组的子矩阵和等于k的问题?** (能否将前缀和思想扩展到二维场景?时间复杂度如何变化?) 4. **哈希表查找操作是否存在优化空间?** (考虑布隆过滤器等概率数据结构对超大数据的适用性) [^1]: 前缀和转换公式:$\sum_{i=l}^{r} arr[i] = prefix[r] - prefix[l-1]$ [^2]: 哈希表优化使查找操作降至$O(1)$均摊时间 [^4]: 滑动窗口法要求数组元素非负
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值