百科问答小站 logo
百科问答小站 font logo



为什么信息竞赛题题解较多使用缩写、魔数、宏定义? 第1页

  

user avatar    网友的相关建议: 
      

竞赛的代码不需要可读性,可维护性,可拓展性。可以称之为:一次性代码。题目通过了就OK,哪怕过后自己都看不懂(夸张了)也无所谓。而做产品却需要考虑代码可读,可维护,可拓展等等。完全相反。

用算法书做例子没任何意义。书是给人读的,可读性是第一位的,必要时候还采用伪代码,甚至流程图。代码却不是。一般不需要别人读懂,最多最多,另外俩队友能懂就可以了。

另外,到底是什么给你错觉,竞赛的人都没有读过《设计模式》《重构》《代码大全》《代码整洁之道》这类的书???做项目的时候,人家写得代码未必比你差哦。


另外,题主贴的代码,完全不觉得混乱。至少没有预定义一堆宏。不少竞赛选手,for循环之类的都是宏定义。

举例子:(十年前竞赛中个人常用的,不完全)

a,b,基本就是普通变量了

c,可能是count,或者写cnt;也可能是单个字符char

d,可能是距离distance,几何,图论常见

e,可能是误差error,或eps;也可能是边 edge,图论常见

f,可能就是函数function,dp的状态转移方程直接写过来的。也可能是流flow,例如在最大流算法的时候

g,也常用作函数,数学的习惯。也可能是图graph

h,也可能是函数,也可能是高height,也可能表示heuristic,也可能是高位置的high

i,j,k常见循环变量,下标

l,可能是长度length,可能是左侧left 或者低位置low,也有时就做普通循环变量。(ll是long long,用cpp答题的可是常见了)

m,一般是个数之类的,也可能是中间middle;也可能是模modulo

n,一般表示个数,可能是是node节点;也可能是下一个next,也写nxt

o,不常见,尤其容易和0混了。O可能表示圆心。oo表示无穷,象形数学的无穷大符号。

p,一般用作指针pointer。偶尔也特指父节点parent。

q,从p过来的,需要第二个指针时,一般考虑q

r,半径radius,余数remainder,右侧的right

s,字符串string,也写st,str;也表示源点source,也写src

t,临时变量temporary,也写tmp,temp;也表示汇点/目的地,也写dst;也表示树tree(树也常用rt,即根root表示)

u,v,图论的点或边,图论书就常用这俩字母

w,权重weight;宽度width

x,y,z,基本和数学一样,表示坐标,几何题常见。非几何的话,不多见

多字母的就更多了,有很多都是缩写,而且是学术界公认的缩写。

比如rmq,lca这些,不学算法的话,你知道啥意思?

看到st,能想到sparse table,想到倍增算法?

看到dc3,能想到difference cover, size 3,想到计算sa(suffix array,后缀数组)?

看到fft,能想到快速傅里叶变换?

看到kd,能想到是k-dimensional tree?


没见过的东西多了,自然就看不懂代码了。计算几何,组合数学,初等数论,数据结构和算法(包含了图论)等等多看看书,就能看懂绝大部分竞赛的代码了。


user avatar    网友的相关建议: 
      

你说的a、b、T、s、t、f、dp什么的,其实在OIer中(至少是写这道题的OIer脑子里)都有固定的含义。(如果没有,那么这个含义可能在问题描述中给出)而不是乱写的。

就像物理学中,每种物理量都用一个字母表示,而不是一串中文或英文表示,这是很自然的。

这也不是什么OIer独有的,“文学”伪代码(如算法导论)中多的是这样的单字母变量。

不过这两者和OIer的区别在于人家可以用符号,OIer只能用n,算导可以写|V|,物理学的导数、积分等各种符号更是给人一种高级感。


代码规范和看不看得懂程序也没多大关系,你要没听懂算法,直接看复杂点的算法代码就是找死,不管那个算法用了多nb的“规范”把注释“蕴含”在变量名中。

你可以去著名的“工程代码”如gnu c++ pb_ds或者Java标准库源码或者认真以让人看懂为目的编写的“文学代码”如算法导论,看看那些算法实现(不看注释、代码外的注解),看看能不能看懂。

至于OIer的注解,正如上述“工程代码”“文学代码”一样,是写在整体代码之外的,OIer一般用md等方式编写于整个代码之上这和“工程代码”编写一大坨注释于整个代码之上与“文学代码”编写一大坨注解于代码之下没什么区别。

当然OIer的题解中往往又有一小部分约定俗成的内容,需要递归学习,这和论文里的引用、”工程代码“上的注释里贴个网址是一样的。(当然,OI比赛场上这些都是不可能去写的)

只有写OIer称之为“模拟题”,研究者称之为“trivial”,或者工程上称之为“业务逻辑”的代码时,才能得到“好的”代码不需要注释就能看懂的结论,在此基础上由于存在“让人看懂”的需求,才会产生“代码简洁之道”这样的要求来满足看懂的同时尽量减少工作量(交接或写注释的工作量)。

而OIer的代码,虽然部分仍属于研究者的“trivial”范围内,但已不适用“好的”代码无需注释就能让人看懂,同时让人看懂的需求也不甚强烈,为此编写出来的尽量减少工作量的代码就如你所示。


PS:你应该庆幸没有看到以让人看不懂、编译器能识别的最短代码等为目的而编写的代码。


user avatar    网友的相关建议: 
      
没想到来回答的全是学竞赛的

顺手刷到这里,看到这句直接喷了出来。

这个问题竞赛生不回答谁回答?题主的目的是吸引广大程序员喷OI吗?


user avatar   the-colored-brown 网友的相关建议: 
      

现身说法:鄙人搞竞赛的时候不敢说前1%,至少也是代码风格比较好看的前10%吧,我是会尽力把代码弄得易读的,因为我有一种搜集个人历史代码的爱好。。。

先说lz贴的这份代码,之所以觉得不好看,其实主要问题不是别的,只是“ll”满天飞,“ll”满天飞的唯一原因,是每次都敲“long long”这九个字母太费劲了,为什么要把这么多变量设置成long long呢(其实我认为这份代码的作者大意了,如果让我来,我会把循环变量i也设成long long,整个代码里找不到一个int)?因为否则的话,没准忘了哪个地方,就数值overflow了,你跺你也麻,真的。。。

至于inline和void缩成il和vd,这个属实意义不大,应该属于一种强迫症行为吧。。。

这里我要指出一点:考场机器上只有devc++或者codeblocks这样的IDE,自动补全不好用,这个是很重要的。。。

其实我倒是觉得,如果考场能用Visual Studio那种级别的,敲两个字母按tab自动补全,打错也能模糊联想的编程环境,那没准大家确实会把命名弄得漂亮些,毕竟除了少数签到题/工程题,对手速的要求也真没那么夸张,尤其是一共就三道题的中学竞赛,毕竟智力输出速度是个瓶颈。。。

在没有自动补全的情况下,难道要手敲包含>=1个完整单词的变量命名,一个字都不能错?你当我傻啊。。。

但是,以我的经验,变量名弄讲究点,也就仅此而已了,剩下的什么运算符打空格,多换行云云还是不太现实的,这里有三个因素:

1、竞赛代码极度依赖肉眼排查算法错误,这要求所有重要代码块都能“一眼看过去”,因此行之间必须安排得比较紧密(比如我一直是大括号不换行党),甚至不能打空格,以缩小显示宽度(你知道中学集中采购的显示器分辨率有多完蛋吗),这就是lz贴的代码里面,setN()函数里面那个while写成一行的原因。。。

2、竞赛代码只有一个.cpp,不能运用工程中常用的声明-定义分离方法。况且其中大部分都是逻辑模块,而不像实际工程中有大量的代码接口,这导致没有必要像工程中那样,用接口本身的定义方式去展示接口的内容,因为实际的内容都在里面。。。

3、背模板(像最短路这样的经典算法模块)这事讲究一个练死劲(雾),也就是讲究一个完全的精确性,在背的时候,甚至会不自觉地精确到“哪个变量声明在什么地方”这样的程度。这就要求不开代码补全以避免干扰(不同环境中不同的代码补全配置可能会影响背默模板的手感,这是很致命的),也要求把这些模板弄得非常精简,以便于记忆和对比记忆检查。这可以解释为什么lz贴的代码里面,pow()函数的那个while循环搞得这么紧密,更新x和更新y也要写在同一行(我猜测这是作者的记忆方式,更新x和y在一起,否则容易漏一个)。举个例子,floyd算法的三个循环变量,竞赛界的祖宗之法是分别叫做k、i、j,你换成什么middleNode,startNode,endNode试试,是不是记忆难度一下子就上去了。。。

说个趣事,敝中学的竞赛教练大概是得知了“windows下用MinGW编译”,然后按照自己的理解,在教学中把我校统一的编程工具定成了MinGW IDE,惊不惊喜,意不意外。。。

这玩意没有任何能用的自动补全功能,导致我在相当长一个时期内,哪怕换成devc++,也要手动关掉自动括号补全,每写一个函数都敲一次shift+{再敲一次shift+},无他,肌肉记忆习惯了。。。




  

相关话题

  你见过最烂的代码长什么样子? 
  请问大佬们能2000行代码0 error 0 warn 0 bug一遍过吗?如果能过,是什么水平? 
  室友打了二十行代码,有三十个错误,他还适合编程吗? 
  在业务需求完全一致,技术指标要求不一致时,是否应该为此提供使用不同优化算法的接口? 
  if嵌套的代码风格哪种好? 
  编程中如何给变量命名?有哪些规范的做法值得学习借鉴? 
  if嵌套的代码风格哪种好? 
  打这样的代码用了一小时零十分钟,大概是个什么手速?(我是初学者中的初学者)? 
  为了软件更符合开源风格,c/cpp 代码缩进应该使用4空格还是2空格? 
  这种代码命名规范,到底好不好? 

前一个讨论
韩国花样滑冰女单在金妍儿之后,为什么不行了?
下一个讨论
带孩子去机场接家人来过年,孩子很好奇机场选址为什么会这么远?有哪些机场是建在市区的吗?





© 2024-12-23 - tinynew.org. All Rights Reserved.
© 2024-12-23 - tinynew.org. 保留所有权利