信息学_一些常见的代码调试方法
本文章同时发表于:微信公众号(万物皆可编程),洛谷GWBailang的Blog
(一只蒟蒻自己总结的)
一,低级的语法错误
把所有的单词拼写都检查一遍,如main不要写成mian
要输出数组中的某个数等,别光写数组的名字!
int a[1005];
...
a[i]=1;
cout<<a<<endl;//错的!
这样不会编译错误,但是输出的……你可以自己试试
二,不输出、死循环等
1 一步一步的找出程序S在了哪里:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
while(n--){
//cout<<"OK"<<endl;第一个
for(int i=1;i<=n;i++){
//cout<<"OK"<<endl;第二个
for(int j=1;j<=m;i++){
//cout<<"OK"<<endl;第三个
n++;
}
}
}
cout<<n<<endl;
//很明显这是个死循环
return 0;
}
分别在每个循环的开始输出一个明显的字符或字符串,注意,单次运行最多只能写一个用于判断死循环的输出,不然你根本不知道程序S在哪里了。
如果某次“OK”被疯狂输出,说明程序就是S在这层循环里了。当你只打开上面这个程序里的“第三个”输出,你会发现“OK”被疯狂输出,而除了它以外其它几次都只输出了一遍,这说明我们的程序S在了这一层,仔细观察就不难发现:j++被写成i++了,当然,n++也是会S的呵。
2 一些特殊的S
如果你的程序里有n%m,n/m之类的运算,那么如果m等于0的时候,电脑就会“因为智商不够”(除数不能为0!)而嘎嘣脆~
所以,你可以用if之类的语句来防止除数等于0。
三,样例死活不对
1 有可能是定义时的问题
例如int数组被定义成了bool,本狼之前做过一题,本来应该定义为int,结果手滑写成了bool,怎么调都不对,样例一直输出1……
bool b;
...
for(...){
b++;//bool形的要么是0要么是1
}
cout<<b<<endl;//所以输出的要么是0要么是1
对了变量名不要写错。容易:本来这块要用n,后来改了方法,这块应该用m,但是还是用的n……
轻则出负数,重则不输出!
(多押韵!)
2 在程序的中间输出一些东西
注意初始化!
在一些赋值、改变变量的值的下一行输出这个变量,看看是不是改变时出了错。手算一遍理想中样例应该输出的值(不会还有人不知道大数可以用电脑上的计算器算吧),再运行程序对照一下。
int a;
...
a=m*n-k;
cout<<a<<endl;//输出一下!
3 如果有函数
最好是把每个函数都单独搁到一个程序里去运行一下看看对不对。如果整体看的话你根本不知道是哪个函数有错
同理,你可以在每次循环、函数调用结束的时候输出一下所有的变量。
四,样例输出没有问题,但是提交后 听取WA声一片
1 WA
同“三-2”一样调
当然,数据需要自己造,除非你下载测试点数据。
如果题目有些要求例如1<ai<10^9
(接近10^9),最好开long long!
注意一些特殊情况,例如需要输出-1等要求!有时题目会有一些输出的要求,可别多个空格或者少个空格的!亏死了
2 RE
基本分为两种:数组下标越界、程序结束返回“1”。
数组下标越界:再好好看看题目要求,或者直接让数组大小*10(就是加个0)
程序结束返回1就很好改了,例如return,exit()等,把1改成0就好了
3 TLE
有可能是算法问题,这个不讲。
当然你可以把cout改成printf类似。不过一般作用不大。或者直接开O2优化呵呵
记住,不要随便用快读函数,事实上快读函数比cin还要慢!
4 MLE
有些可能是算法问题,不讲
根据程序和算法,一些可以不在循环里定义的变量、字符串等,就不要在循环里定义!
...
string s;
while(...){
//不要在循环里面定义s
...
}
5 AC
AC不一定就代表你这个程序在运行这个测试点的时候,一定是对的。有可能只是凑巧结果对了!