(8.30 更新) 题解提交注意事项

回复帖子

@一扶苏一  扶咕咕 2020-08-05 00:45 回复

2020/8/30:新增三个不良现象。


之前 @StudyingFather 已经在他的 blog 里向大家说明了应该如何写出一篇排版整齐美观的题解。目前,题解的格式问题已经有了较大的改观。近期的后台审核过程中碰到的大多数题解排版都已经基本符合要求。但是,在题解的内容方面,仍然存在一些问题,因此这里发布这一篇帖子,总结最近在审核过程中碰到的问题。

首先想请大家理解的是,被选入洛谷题解区的博客,其首要目的是为了给其他用户提供解法上的参考。因此投稿题解在书写的过程中,因该尽可能的以方便读者为目的,如果一篇入选题解区的博客给读者造成了不必要的困惑,或者无意义的占用了读者的时间与精力,那么该博客就不应该出现在题解区中。本着这个原则,我们希望题解在能给读者提供解题方法的同时,能够尽量精简。

因为好多题解当中的不良现象只有管理员见过(因为根本不会通过审核),所以您可能并不能完全理解下面的部分情况。不过这恰好说明您没有这样的问题。

目前提到的几种不良现象:

错误做法占比过多

详细程度与题目难度不匹配

重视代码实现忽略思考过程

无意义重复代码

无意义内容占比过大

在题解里求 debug

只提供结论的题解

事无巨细加注释

把做法作为注释写在代码里。

一、错误做法占比过多

这类博客主要出现于较简单的题目题解中。在这类题解中,作者往往用大量的笔墨去描述自己一开始的与正解基本无关的错误想法,并且在叙述时不提前对「内容是错误的」加以注明。有一篇典型反面教材样式如下:

首先拿到这道题目,我们的第一印象是……

因此我们可以想到……

从而……

然后……

就可以……

……

代码:

**但是,上述做法是错误的**,我们需要从头重新考虑。

正确的做法是……

最终代码:

这种博客的弊端是显而易见的。首先前面七行叙述了一个与正解完全无关的错误做法,甚至给出了一个错误的代码,然后再在下面给出十分简短的正确做法。首先前面的错误做法属于无意义内容,即使删掉这篇博客依然完整,那么就没有必要放在开头以大量笔墨描述,更没有必要给出错误代码。第二,在描述错误做法时不提前注明。如果读者发现了内容的错误,会引起读者无意义的思考,无意义的占用读者的时间与精力。

需要说明的是,即使您认为这个错误非常典型,我们也不建议您在开头直接叙述错误做法。推荐的做法是在叙述完正解后,用简短的一句或一句话写明「一种典型的错误做法是,因为……,导致……,其解决方法是……」,并且不需要给出错误代码。

如果这个错误的做法只是正解少考虑了若干种复杂的情况或其他对正解有较大启发性的情况,我们建议您在叙述开头写明「我们先来分析不考虑……的情况应该如何处理」等文字来说明下面的解法具有一定的局限性。同样不需要给出错误代码。

二、详细程度与题目难度不匹配

这类博客分为两种:简单题分析过少,难题无意义讲解过多。

第一种常见于有一定思维含量的橙黄题目,作者对做法中的结论完全不加证明,只是在几个结论的基础上说明题目应该怎么做。这样的博客是没有意义的。因为对于这类题目,其关键恰恰就在对于结论的证明上。而在已有结论的基础上组合出最终做法相对于得出结论的难度较低,完全不是题目的重难点,无法对读者起到什么正面作用。

第二种常见于难度较高的题目。以「[NOI2015] 寿司晚宴」这道题目为例,有一篇提交审核的博客在开头用了几乎一屏的内容说明「什么是位运算」「什么是状压 dp」。显而易见,作为一道黑色难度的 NOI 题,来试图解决这道题目的选手不可能对于位运算和状压 dp 的基础知识都不了解。这些内容显然无法对读者起到任何的帮助作用,基本没有意义。

一般而言,对于新手常接触的入门题目,我们希望题解能够写的尽量详细,来减少新手的困惑;而对于难度较高的题目,则应该省略一些读者显然都会的基础知识部分,突出题目的重点。事无巨细的详细列出所有的内容只会让博客变得冗杂而不会增加它的价值。

三、本末倒置,重视代码实现却忽略思考过程

常见于简单题中。诚然代码实现是算法竞赛中必要的一部分,但是算法竞赛毕竟不是「编程能力大赛」,对于大多数题目,代码实现只是做题过程中非常小的一个小部分。很多时候对题目的分析远比如何实现代码更重要。事实上当水平提升到一定程度后,代码实现将完全不是做题中的障碍。并且各人的代码习惯不同,实现代码的方式也不同,如果一篇题解只注重与如何写出代码,而不对题目本身进行分析,那么这篇题解的意义就大打折扣。当然,对于入门题目和其他合适的题目,我们赞成适当的讲解一些实现思路和技巧。

四、无意义重复代码

很多人的代码习惯是

#include <cstdio>

void Solve() {

  //do sth

}

int main() {

  Solve();

  return 0;

}

显而易见,整篇代码的核心全在 Solve 中。如果在文字叙述过程中已经将 Solve 函数的代码给出,那么在博客末尾就不再需要给出完整代码。两部分代码的内容并没有什么本质区别,反而令博客十分冗余,在这种情况下,在文字叙述部分给出 Solve 函数的代码也看不出有什么意义。

同样的,先打了一遍板子,然后加上 main() 和输入输出又发了一遍(来自 @Anguei 的原话)也是无意义内容。

五、无意义内容占比过大

主要针对这类博客:

编号:P1002

难度:普及-

算法:dp

……(省略 50 行废话)

---

下面正式开始讲解!

(两行结束)

---

完结撒花~

还有这类博客:

我先来吐槽一下题面

(吐槽了 50 行)

下面来说正解

……
我们先来看一下日文题面:

(复制一段日文)

我们再来看一下翻译:

(复制一段翻译)

我们再来看一下输入输出:

(讲了一遍输出是怎么来的)

……

以及这类博客:

# 大家好,我又来给大家上课了!

我们都知道……

# 诶,那个走神的,出去站着!!

……

肉眼可见,前两种博客的前 50 行都是无意义内容。我个人并不反对在博客中偶尔掺杂一些个人吐槽或者抖机灵,亦或是加入个人对题目的一些记录,但是应该尽量简短,最好可以用一两句话写完。这类内容如果喧宾夺主,显然不能称为一篇优秀的题解。而第三种博客对题面的复制和样例讲解都属于无意义内容。至于第四种博客,请不要写题解的时候给自己加戏,这样看起来非常无聊

六、在题解里求 debug

我觉得这应该是一个显然不正确的行为,但是在审核中确实碰到了不少这样的博客。请注意题解区不是讨论版,是用来提供做法的,不是用来求助的。如果做题存在困难,请在讨论区发帖求助。

七、只提供结论的题解

常见于 cf 的前几题和一些找规律题。

只提供规律/结论对于读者是完全没有帮助的,例如:

## Analysis
这题很简单,经过打表找规律,可以发现答案是  $a \times b - a - b$。

对于可以通过找规律推出式子或直观看出结论的题目,我们要求对于式子或结论给出严谨的证明或推导过程,而不是仅仅以“找规律”带过。

证明过程中,对于严谨证明十分困难或者占用篇幅过大的非核心结论,如果该结论十分直观,可以只简单的说明理由。

八、事无巨细加注释/把做法作为注释写在代码里

题解代码中的注释应该只用于标注关键内容位置。对于内容/做法的说明应该写在文字说明里,而不是代码注释里。对于不重要的非关键内容,不应该予以注释,从而保证代码主次得当。否则会给读者造成严重的阅读障碍。下面是两个反例:

#include <cstdio> // 这是头文件,我们使用 scanf 需要用到它

int main() {
  long long int a, b;  // 定义两个变量,一个叫 a,一个叫 b。
  scanf("%lld %lld", &a, &b); // 输入变量
  printf("%lld\n", a * b - a - b); // 输出变量
  return 0; // 好习惯
}
#include <cstdio>
...
int f[maxn][maxn];
/*本题 f 数组表示当前坐标点滑下去的最大长度。
状态转移方程:f[i][j]=max{f[i±1][j]+1,f[i][j±1]+1,f[i][j]}
dfs函数采用逆推法。 
*/ 
void dfs(const int x, const int y) {}
...
​```

对于第一个例子,所有的注释都是废话,可以全部删除。全都是注释等于没有注释,纵使有不应删除的注释,因为废话太多,不应被删除的注释也不会被读者看见。这类题解会以「无意义内容」为理由拒绝。

对于第二个例子,应该把转移方程和实现方法以文字说明的形式给出。文字说明有 LaTeX 的帮助,在可读性和整齐性上会有很大提升。写在代码里的说明因为查找不便且需要阅读代码等原因,效率十分低下。这类题解会以「说明过少」为理由拒绝。

@phil071128 2020-08-05 05:24 回复 举报

好评,希望每一篇题解都能体现出该题目的真正做法,让那些非常好的代码置顶

(另外P1216作为一道IOI的题讲入门DP不过分吧)(doge)

当然现在一些初学者根本没有机会去发很多的题解,因为普及-以前的题目基本上都满了(哭~)

反馈
如果你认为某个帖子有问题,欢迎向洛谷反馈,以帮助更多的同学。



请具体说明理由,以增加反馈的可信度。