Common Mistakes
This page mainly shares the mistakes commonly made in the competition.
Could Cause Compile Error¶
We left the detailed explanation out since this type of errors is pretty straightforward and self-explanatory.
-
Use
int mian()
instead ofint main()
. -
Forgets to write a semicolon after
struct
orclass
. -
If the array size is too large, or an illegal function (such as multithreading) is used on OJ, or the function is declared but undefined, it will cause the link error.
-
When using the
max
function inalgorithm
, one parameter hasint
type and the other one haslong long
type.- Example:
printf("%lld\n", max(0, query(1, 1, n, l, r)); // query returns long long type
- Example:
-
Skipped the initialization of some local variables while using
goto
.- Skipped the initialization of some local variables while
switch-case
.
- Skipped the initialization of some local variables while
Does not cause Compile Error but will cause Warning¶
This kind of error is hard to find, but it will be pointed out by the compiler when compiling with the -W{warningtype}
parameter. You might want to check out the Warning Options in the official documentation. Common ones in -W{warningtype}
include -Wall
, - Wextra
, -Wshadow
, etc.
-
Error caused by operator precedence .
1 << 1 + 1
: 1 is left shifted by 2, that is, the value returned by the expression is 4.
-
The
static
modifier is used incorrectly. -
-1 >> 1 == 1
-
Cannot distinguish between assignment operator and
==
.- Example:
No matter what the previous value of n was, the output must beif (n = 1) puts("Yes"); else puts("No");
Yes
. Tips: If you really want to use the assignment operator (such aswhile (foo = bar)
) directly inif
/while
, and you do not want to receive warnings, you can use double brackets:while ((foo = bar))
.
- Example:
-
Forgets to add the address character
&
when reading usingscanf
. More generally, when usingscanf
orprintf
, the parameter type does not match the format specifier. -
Did not consider the case of negative array index.
-
Use both bitwise and logical operators (
==
) without parentheses (eg(x>>j)&3==2
). -
int
literal overflow, for example:long long x = 0x7f7f7f7f7f7f7f7f
,1<<62
. -
Uninitialized local variables, causing local variables to be assigned with initial undefined values.
-
The local and global variables have the same name, causing the global variables to be accidentally overwritten. (Open
-Wshadow
to check for such errors.)
Causes neither Compile Error nor Warning¶
Such errors cannot be discovered by the compiler, so you need to rely on yourself when debugging.
Could Cause WA¶
-
Forgets to clear all for multiple sets of array input.
-
Forgets to check negative numbers when using reading optimization.
-
The data type used is not large enough, causing overflow, which means that the usage of
long long
(openinglong long
) leads to losing a large number of points. -
Forgets to -1 when reading input graph whose endpoint number starts from 1 but those defined in your graph starts from 0.
-
or < sign are wrong or reversed.
-
After executing
ios::sync_with_stdio(false);
, the usage of two IOs are mixed, resulting in messy input/output.- Example:
// This example will illustrate the consequences of mixing two IOs after turning off synchronization with stdio // It is recommended to use single-step operation to observe the effect #include <cstdio> #include <iostream> int main() { std::ios::sync_with_stdio(false); // After the synchronization is turned off, // cin/cout will use separate buffers // instead of synchronizing the output to the scanf/printf buffer, // thereby reducing IO time std::cout << "a\n"; // In cout, when using'\n' line feed, // the content will be buffered and not output immediately. // You should use endl to wrap and refresh the buffer immediately printf("b\n"); // printf'\n' will flush printf's buffer, causing the output to be misplaced std::cout << "c\n"; return 0; // At the end of the program, the buffer of cout will be output }
- In particular, you cannot use
freopen
after executingios::sync_with_stdio(false);
.
- Example:
-
Errors caused by macro expansion without parentheses:
The value returned by this macro is not 4^2 = 16 but 2+2\times 2+2 = 8.#define square(x) x* x printf("%d", square(2 + 2));
-
When hashing,
unsigned
is not used, because the right shift operation for negative numbers will be complemented by 1 at the highest bit. For details, see Bit Operation -
Forgets to delete the debugging information.
-
Add
;
by mistake.- Example:
/* clang-format off */ while (1); printf("OI Wiki!\n");
- Example:
-
The sentinel value is not set correctly. For example, the
0
node of a balanced tree. -
In the constructor of a class or structure, use
:
to initialize the variable, and the variable declaration order does not meet the dependency at the time of initialization. This is because the order of initialization of member variables is only related to the order in which they are declared in the class, but not the order in the initialization list. -
Forgets to merge the ancestors of the two elements when merging two union-find sets,
f[a] = b; // right
f[find(a)] = find(b); // wrong
Could Cause RE¶
-
Divide the integer by 0.
- Inverse 0.
-
Forgets to delete the file operations (for some OJs).
-
Errors in comparison functions when sorting.
std::sort
requires comparison functions to be strictly weakly ordered:a<a
isfalse
; ifa<b
istrue
, thenb<a
isfalse
; ifa<b
istrue
andb<c
istrue
, thena<c
istrue
. Pay special attention to the second point.If the above requirements are not met, it is likely to be RE when sorting.
For example, when writing the parity order of the Mo's Algorithm, this is wrong:
bool operator<(const int a, const int b) { if (block[a.l] == block[b.l]) return (block[a.l] & 1) ^ (a.r < b.r); else return block[a.l] < block[b.l];
In the code above,
(block[a.l]&1)^(a.r<b.r)
does not meet the strict weak order in requirement 2.Changing into this would make it correct:
- Dereferencing the null pointer.bool operator<(const int a, const int b) { if (block[a.l] == block[b.l]) return (block[a.l] & 1) ? (a.r < b.r) : (a.r > b.r); else return block[a.l] < block[b.l];
Could Cause TLE¶
-
Divide and conquer without boundary check leads to recursion.
-
Dead loop:
-
Use the same name for the loop variable.
-
The direction of loop is reversed.
-
-
Forgets to mark whether a state has been visited in BFS.
-
Use macro expansion to write min/max.
Although this approach technically is not an "error", it still needs to be mentioned here.
The common way of writing looks like this:
#define Min(x, y) ((x) < (y) ? (x) : (y)) #define Max(x, y) ((x) > (y) ? (x) : (y))
Although there is no problem in the correctness of this writing, if you directly take the max of the return value of the function, such as
a = Max(func1(), func2())
, and the running time of this function is longer, the performance of the program will be greatly affected. Because after the macro expanded, it will bea = func1()> func2()? Func1(): func2()
. The function is called three times, which is called once more than the normal max function.This kind of error is especially common when a beginner writes a segment tree, which will greatly increase the running time of the program and even directly affect the time complexity of the code. For example, this error code:
#define max(x, y) ((x) > (y) ? (x) : (y)) int query(int t, int l, int r, int ql, int qr) { if (ql <= l && qr >= r) { ++ti[t]; // Record the number of node visits for easy debugging return vi[t]; } int mid = (l + r) >> 1; if (mid >= qr) { return query(lt(t), l, mid, ql, qr); } if (mid < ql) { return query(rt(t), mid + 1, r, ql, qr); } return max(query(lt(t), l, mid, ql, qr), query(rt(t), mid + 1, r, ql, qr)); }
Will be stuck to a single query \Theta(n) leading to TLE.
-
Forgets to delete the file operations (for some OJ).
-
for (int i = 0; i < strlen(s); ++i)
: Repeatedly execute functions with complexity other than O(1) in the loop. (Strictly speaking, this may cause a change in time complexity.)
Could Cause MLE¶
-
The size of the array is too large.
-
Too many elements are inserted in the STL container.
-
It is often an endless loop that inserts elements into the STL.
-
It may also be stuck.
-
Undefined behavior¶
-
The array is out of boundary. Either the starting point or ending point. (Mostly RE.)
-
Fail to set the initial value of the loop correctly, leading to the access to the value with index -1.
-
The undirected graph edge table is not declared twice the size.
-
The segment tree does not declare 4 times the space.
-
Miss a zero in delcaration because reading the data range wrong.
-
Miscalculates the space complexity of the algorithm.
-
When writing a segment tree,
pushup
orpushdown
leaf nodes.
-
-
Dereference wild pointers.
-
The pointer is dereferenced without initialization.
-
The area pointed to by the pointer is already
free
ordelete
.
-
Cause time complexity constant to be too large¶
-
When defining the modulus, a global variable (such as
int mod = 998244353
is used. For the convenience of compiler processing by constants, the correct practice isconst int mod = 998244353
). -
Unnecessary recursion is used (note that tail recursion is not included).
-
When converting recursion into iteration, a lot of extra operations are introduced.
Errors that only take effect when the program is running locally¶
-
Errors that may occur during file operations:
-
If the file pointer is not cleared during the double compare, that is,
fclose(fp)
, thenfp = fopen()
, which will cause a large number of file pointers in the process. -
The file names in
freopen()
are not added with.in
/.out
.
-
-
Forgets about
delete
orfree
while using the heap space.
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:OI-wiki
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用