新手避坑指南:用C语言数组模拟解决‘移树问题’,为什么你的程序可能超时或出错?
第一次用C语言解决"校门外的树"这类模拟题时,我盯着屏幕上"Wrong Answer"的提示整整半小时。明明测试样例能通过,为什么提交后总是出错?后来才发现,问题出在数组下标的一个微小越界上——这种错误在初学者代码中几乎像传染病一样普遍。本文将带你拆解这道经典题目背后隐藏的四个致命陷阱,并提供可直接复用的调试技巧。
1. 数组越界:为什么你的程序随机崩溃?
假设马路长度L=10000,你会定义多大的数组?很多新手会直觉地写下int c[10000],然后在循环中访问c[10000]——这正是段错误的根源。C语言的数组下标从0开始,这意味着:
c复制// 危险代码示例
int c[10000]; // 有效下标是0~9999
for(int i=0; i<=10000; i++) { // 当i=10000时越界
c[i] = 1;
}
正确做法:数组大小应比最大下标多1。对于L=10000的情况:
c复制int c[10001]; // 包含0~10000共10001个元素
提示:养成定义数组时检查边界的习惯,可以用
#define MAX_L 10001这样的宏来避免魔法数字。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 循环边界:那个等号到底该不该要?
观察题目样例输入:
code复制2
500 3
150 300
100 200
470 471
当处理区域470-471时,以下两种写法有本质区别:
c复制// 写法A:可能遗漏端点
for(i=a; i<b; i++) { c[i] = 1; }
// 写法B:完全覆盖区间
for(i=a; i<=b; i++) { c[i] = 1; }
关键验证:用极端情况测试,比如区间0-0或500-500。如果漏掉等号,这些单点区间会被完全忽略。
3. 多组数据初始化:为什么第二次测试总是出错?
参考代码中的int c[10000]={0}看似初始化了数组,但放在while循环内部意味着每组数据都会重新清零。如果误将其移到循环外部:
c复制int c[10001] = {0}; // 错误的放置位置
while(n--) {
//
