【OI干货】一个小小的Coding经验总结

· · 个人记录

持续更新ing...

* 自用,请勿搬运or转载,分享随意 *
* 这里是一只小小小小小白,求勿杠求轻喷qvq *

写在最前面:在你向任何人求助之前,请一定要认真阅读这一篇==>How To Ask Questions The Smart Way 或 How To Ask Questions The Smart Way 简体中文版 或 关于如何提问的一张思维导图 - 0xFFFF

Ⅰ. 关于OJ里面各种常见的评测状态和出现的原因

AC: Accepted(答案正确)

恭喜你的代码通过了全部的测试点( ̄▽ ̄)~* 太优秀啦///

CE: Compile Error(编译错误)

p.s. 一般来说数组作为局部变量时最长的长度:int数组的最大范围是500000(估计)、char类型的最大范围是2000000;全局变量则可以定义更长的数组。(详情见对于c++中数组的最大长度的理解 - 二十四桥明月夜的博客)

WA: Wrong Answer(答案错误)

RE: Runtime Error(运行时错误)

TLE: Time Limited Error(超出时间限制)

MLE: Memory Limited Error(超出内存限制)

PE: Presentation Error(格式错误)

【最近进行的SCNU-N热身赛里面的D题就是典型例子,很多人因为冒号后面漏了个空格而陷入WA的debug中XD(正式ACM赛里面会有这个报错)。一个取巧的方法就是可以拿鼠标光标去选一下Sample输出,看看里面哪个地方藏了括号之类的。】

Ⅱ. 码风

强烈安利这个视频[av3929318](和这个视频的up主!)->【原创教程】代码规范_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili 不要求都按视频里的来啦,完全可以看个人喜好的www 但最重要就是要整齐和统一。

最最基本的排版要求:至少你同一层的代码缩进得相同吧√

For example:

//第一层
bool isPrime(int num){
    //第二层
    for(int i=2;i<=sqrt(num);i++){
        //第三层
        if(num%i==0){
            //第四层
            ++cnt;
            return 0;
        }
    }
    return 1;
}

变量命名方法(不要再用abcdef啦!)

  1. 匈牙利命名法:iCount,iSum,cName
  2. 驼峰式命名法(Camel-Case):stuName, StuName
  3. 下划线命名法:student_name

Ⅲ. 应该要拿个小本本记下来的东西

讲真学C++的时候要记的东西真的不多,但有些东西记住了真的很有用↓

常用头文件及函数

#include <cmath>
    abs(num);
    sqrt(num);
    pow(a,b); //a^b

#include <cstdio>
    scanf("%d",&num);
    printf("%d",num);

#include <iomanip> //精度控制
    cout<<setiosflags(ios::fixed)<<setprecision(2)<<num;

#include <algorithm> //偷懒专用库(初学者不建议使用
    sort(num,num+n); //把num[]从小到大排列
    swap(a,b); //交换a和b
    max(a,b); //返回a,b的较大值
    min(a,b); //返回a,b的较小值

#include <cstring> //操作char数组
    char str[100];
    int len=strlen(str); //返回字符串长度
    strcat(str1,str2); //把str2连接到str1后面
    strcpy(str1,str2); //即str1=str2
    cout<<strcmp(str1,str2); //返回两字符串左起第一个不相同的字符的ASCII码的差值
    cout<<strlwr(str); //把str的全部字母转化成小写字母并输出
    cout<<strupr(str); //把str的全部字母转化成大写字母并输出
    memset(num,0,sizeof(num));
    //memset可用于初始化数组(这里把num[]初始化为0),但是以字节为单位的(第三个参数)。一般初始化为0或-1(二进制补码都为0或1)

#include <bits/stdc++.h> //万能头文件,包含了常用的一大堆库,但目前有些OJ或比赛不支持,慎用

ASCII码

没必要全部都记,但总要记些特别的。比如:小写字母=大写字母+32以及A~Z、0~9和a~z的相对位置(谁在前谁在后)。

常用数据类型的范围

(以下均为有符号数,无符号数则翻倍。)

  1. int 4bytes(32位,大概2.1e10)
  2. long long 8bytes(64位,大概9.2e18)
  3. double 8bytes(64位,浮点数)

格式控制符

%d -> int
%o -> 以八进制形式输出
%x -> 以十六进制形式输出
%lld -> long long
%lf -> double
%c -> 单个字符
%s -> 字符串

Ⅳ. 关于DEBUG

静态查错

简而言之,就是你一直瞪着你的WA代码,说不定瞪着瞪着就发现哪里有问题了呢^_^。

反正就是逐条语句分析,必要的时候可以拿起手边的草稿纸,手算模拟一波。

↓比如这是上面提到的P1426 小鱼会有危险吗的WA代码,无奖竞猜错误在哪x_x。

#include<iostream>
using namespace std;
int main(){
    int sum=0,s,x;
    cin>>s>>x;
    for(int i=7;;i*=0.98){
        sum+=i;
        if(sum>=s-x){
            if(sum+i*0.98>s+x) cout<<"n"<<endl;
            else cout<<"y"<<endl;
            break;
        }
    }
    return 0;
}

输出查错

一个我最喜欢用的方法kkkkk 一言以蔽之就是——输出关键值或者关键位置某个变量的值的状态。

比如上面那份代码:

#include<iostream>
using namespace std;
int main(){
    int sum=0,s,x;
    cin>>s>>x;
    for(int i=7;;i*=0.98){
        sum+=i;
        if(sum>=s-x){
            if(sum+i*0.98>s+x) cout<<"n"<<endl;
            else cout<<"y"<<endl;
            break;
        }
    }
    return 0;
}

光看可能看不出来哪里有问题,那么我们可以试试在for循环里加一句【cout<<sum<<endl;】这样可以看到sum在每次循环时的状态值。(当然这里的错误并不是逻辑的问题,所以这么做并不能看出来)

以及,其实这个方法的原理跟编译器自带的debug功能原理相同,能掌握下面的debug方法固然最好,毕竟省时间呀。

运用编译器的debug调试功能

因为不怎么用不再赘述,指路一篇Dev-C++的调试指南:Dev C++单步调试/debug详细图解 - CaprYang的博客

另外给用Linux的小伙伴推一个gdb调试:gdb调试的基本使用 - H&K - 博客园

Ⅴ. 最后接好这堆网站安利ya——

①洛谷(https://www.luogu.com.cn/)

这个不多说啦,刷题好去处。交题没AC的时候先努力思考一下自己的代码存在什么问题,但如果挠破头都想不到哪里有问题的话可以看看这道题目的讨论版,总能发现奇妙的东西(笑

实在过不了再尝试看看题解,学习学习优秀的思路hhhh

p.s.尤其推荐去刷试炼场的新手村,我觉得学完数组那一章以后新手村八个关卡基本上都没问题的啦,对自己有点信心呐。

【2020.09.30更新】↓

新手村在今年上半年被砍了,取而代之的是题单功能(爷青结QAQ 新手村刷题真的很适合入门)。不过题单功能的上线更方便针对某一特定算法进行练习了,同一种算法里各个难度等级都有。

②OI wiki(https://oi-wiki.org/)

一个干货非常非常多的网站,如果有心走竞赛的话可以把它从里到外仔仔细细地刷个几遍,除了侧边栏的介绍和提醒以外,还有顶栏的语言基础和各种算法,应有尽有,肯定能找到你想要的hhhh(包括之前的位运算链接就是出自它的门下)。

③CSDN(https://www.csdn.net/)

一个目前来说发展得比较好的IT中文论坛,虽然里面的博客有很多搬运的,重复率挺高,但早期还是有很多优秀的blog的。一般来说跟计算机有关的科普和问题都可以来这里找。

④0xFFFF(https://0xffff.one/)

SCNUers的搬砖技术社区!本校的论坛怎么能不支持一下呢!(还记得最开始水的时候还看到一篇讲Minecraft mod的帖子) 置顶那一篇计算机入门的帖强推!也强推Linux区的帖子kkkk学到了不少(虽然长期潜水)。

⑤Stack Overflow(https://stackoverflow.com/)

如果能接受英文阅读的话,我强烈推荐这个网站!!很多编程相关的偏门到极点的问题最后都是在这里找到答案的!

而且它会有问题查重,保证剩下的都是比较优质的问题hhhh。当然你也可以在这里提问,只是提问之前请务必记得开头那篇《How To Ask Questions The Smart Way》。

唯一的缺点可能就是外网加载得比较慢吧(但是不用翻墙啊!)

⑥SoloLearn(https://www.sololearn.com/)

这是!一个!好玩的!边学边练的!学语言的网站!也有配套APP!

在这里,你能学到各种语言的courses,通过先阅读基础知识再做一道题的形式,轻轻松松过完语法基础! 还能找人PK一大堆各种各样的语言基础选择题!妈妈再也不用担心我期末考试的程设选择题啦~!(在线C++求战:D 互相PK互相进步)

⑦Github(https://github.com/)

全世界最大的同性交友网站(咳。

GitHub是一个面向开源及私有软件项目的托管平台,简单来说就是能在上面找到很多有趣又好玩的开源项目,可以经常逛逛发现新大陆呐√。

【2020.09.30更新】↓

比如有一个很好玩的fucking-algorithm项目,专门配合LeetCode刷题讲算法的一个很实用的仓库,可以仔细研读一下hhh

⑧CodeForces(https://codeforces.com/contests)

是一个专门跟世界各地的人一起切磋上分的平台,攻略指路 -> Codeforces游玩攻略

题目全英文,跟OJ最大的不同就是比赛有限时机制,可以用来模拟ACM参赛。 体验不足的地方就是很多比赛的时间对东八区不太友好(有时差XD),不过只要肯蹲就还是能发现有ok的时间段的。以及,虽然不用翻墙就能连,但是网速堪忧,交题的时候需要等好久(尤其是快结束的时候,慢到令人抓狂)。

⑨POJ(http://poj.org/)和ZOJ(https://zoj.pintia.cn/home/news)

两个著名的英文刷题OJ,可以锻炼自己的英语读题能力。还有一份流传已久的POJ经典题单,来源不可考:POJ题目分类推荐 (很好很有层次感)

欢迎捉虫,也欢迎大佬们指出不妥之处QvQ感谢阅读biu~

依旧非常欢迎提问呀٩(๑>◡<๑)۶ 互相进步嘛kkkkkk