# P3156 【深基15.例1】询问学号 ## 题目描述 有 $n(n \le 2 \times 10^6)$ 名同学陆陆续续进入教室。我们知道每名同学的学号(在 $1$ 到 $10^9$ 之间),按进教室的顺序给出。上课了,老师想知道第 $i$ 个进入教室的同学的学号是什么(最先进入教室的同学 $i=1$),询问次数不超过 $10^5$ 次。 ## 输入格式 第一行 $2$ 个整数 $n$ 和 $m$,表示学生个数和询问次数。 第二行 $n$ 个整数,表示按顺序进入教室的学号。 第三行 $m$ 个整数,表示询问第几个进入教室的同学。 ## 输出格式 输出 $m$ 个整数表示答案,用换行隔开。 ## 输入输出样例 #1 ### 输入 #1 ``` 10 3 1 9 2 60 8 17 11 4 5 14 1 5 9 ``` ### 输出 #1 ``` 1 8 5 ``` #include <bits/stdc++.h> using namespace std; int n ,m; const int N = 1e6 + 10; const int M = 1e5 + 5; int num[N] = {}; int mum[M] = {}; int main() { cin >> n >> m; for(int i = 1 ;i <= n;i++){ cin >> num[i]; } for(int i = 1;i <= m;i++){ cin >> mum[i]; cout << num[mum[i]] << endl; } return 0; } 我的代码错在哪(这是runtimeeror)
时间: 2025-07-23 16:00:32 浏览: 0
<think>题目中n最大为2e6,而你的数组N设置为1e6+10,这会导致数组越界。
应该将N改为2e6+10或者更大一点。
另外,题目要求学号在1到10^9之间,所以数组应该用long long吗?但题目中询问的是第几个进入教室的同学,而输入时是按顺序进入的,所以只需要用数组存储每个位置上的学号。
由于n最大2e6,学号最大1e9,所以用int存储学号是足够的(1e9在int范围内?注意:int范围是-2^31~2^31-1,即-2147483648~2147483647,所以1e9在int范围内)。
但是数组大小不够,所以将N改为2000010(或者2e6+10)即可。
修改如下:
将 const int N = 1e6 + 10; 改为 const int N = 2000010; 或者 const int N = 2e6 + 10;
另外,注意m最大为1e5,而M=1e5+5是足够的。
但是,你的代码中,输入n和m后,循环读入n个数,下标从1到n,所以数组大小需要至少n+1,而n最大2e6,所以N至少2000001(或2000010)。
所以,问题出在数组大小不够。
修改后代码:
#include <bits/stdc++.h>
using namespace std;
int n ,m;
const int N = 2000010; // 修改这里
const int M = 100010; // m最大1e5,所以M=1e5+10也可以,但原M=1e5+5也够,不过为了保险可以加大一点,比如100010
int num[N]; // 存储学号
int mum[M]; // 存储询问的位置(其实这个数组可以不用,直接边读边输出)
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i++){
cin >> num[i];
}
for(int i = 1; i <= m; i++){
int pos; // 可以直接读入位置,然后输出,不需要存到数组
cin >> pos;
cout << num[pos] << endl;
}
return 0;
}
或者,不修改数组大小,但题目要求n最大2e6,所以必须将N改为2e6+10。
另外,原代码中数组mum其实没有用,因为每次询问可以立即输出,不需要存储。但这不是错误原因。
错误原因:数组num大小不够,导致当n>1e6时,访问越界,造成运行时错误(Runtime Error)。
所以,将N改为2000010(即2e6+10)即可。
注意:题目中n最大是2e6,所以数组大小至少2000001(索引0到2000000),我们通常用1-index,所以需要2000001,因此N=2000010是足够的。
修改后的代码:</think>您的代码存在一个关键问题:**数组大小不足**导致运行时错误(Runtime Error)。以下是详细分析和修正方案:
### 错误原因分析
1. **数组越界访问**:
```cpp
const int N = 1e6 + 10; // 实际最大仅支持 n=1,000,010
```
- 题目要求 `n ≤ 2×10⁶`(200万)
- 当 `n > 1e6` 时(如输入200万),访问 `num[mum[i]]` 会越界
2. **冗余存储**:
```cpp
int mum[M] = {}; // 完全不需要存储所有询问
```
- 询问可即时处理,无需用数组存储所有查询位置
### 修正后的代码
```cpp
#include <iostream>
using namespace std;
int main() {
ios::sync_with_stdio(false); // 加速输入输出
cin.tie(0); // 解除cin与cout的绑定
int n, m;
cin >> n >> m;
// 动态分配数组(或直接使用vector)
int* num = new int[n + 1]; // 索引从1开始使用
// 读取学号序列
for (int i = 1; i <= n; i++) {
cin >> num[i];
}
// 即时处理每个查询
while (m--) {
int pos;
cin >> pos;
cout << num[pos] << '\n'; // 直接输出结果
}
delete[] num; // 释放内存
return 0;
}
```
### 关键修改点
| 问题位置 | 原代码 | 修改后 | 原因说明 |
|------------------|----------------------------|---------------------------|------------------------|
| 数组大小 | `N=1e6+10` | 动态分配`n+1`空间 | 支持最大200万数据 |
| 查询处理 | 预存所有查询位置 | 即时读取+输出 | 节省内存,避免冗余存储 |
| 输入输出效率 | 无优化 | 添加`ios::sync_with_stdio`| 加速大数据IO |
| 内存管理 | 静态数组 | `new/delete`动态分配 | 灵活适应数据规模 |
> **替代方案**:使用`std::vector`更安全(推荐)
> ```cpp
> vector<int> num(n + 1);
> for (int i = 1; i <= n; ++i) cin >> num[i];
> ```
### 为什么原代码导致Runtime Error?
- 当输入 `n=2000000` 时,原代码尝试访问 `num[2000000]`
- 但数组实际大小仅为 `N=1000010`
- 触发**内存越界访问** → 操作系统强制终止程序 → **Runtime Error**
阅读全文
相关推荐















