竞赛犯过的错误反思

一定要先看数据范围

  1. 数组开小了。
  2. 该long long没long long。有时候题面的数据不超int, 但加起来或者乘起来就超int了。

开始写代码之前心里要有底

  1. 要预估一下代码实现的难度,不能走一步看一步。昨天的cf就是一个惨痛的教训比赛链接。本来就是一道模拟水题,但是一开始思路错了,就造成代码量巨大,然后还有可能WA,后期还不好debug。

初始化的问题

  1. 如果是多组样例,比如T组样例这种,那么就需要每次都初始化。如果是要初始化一个数组,那就memset,如果多组的话那就for,一定用多少初始化多少,for到n而不是maxn。前几天的codeforces就是这么T掉的,白白丢掉一道题。比赛链接

代码执行先后的问题

  1. 还是昨天的cf,我犯了一个很蠢的错误。
		for (int i = 0; i < n; i++){
			for (int j = 0; j < m; j++){
				if (M[i][j] == '*'){
					if (flag == 1){
						error = 1;
						ans = false;
						break;
					}
					if (check(i, j)){
						ranse(i, j);
						flag = 1;
						ans = true;
					}
				}
			}
			if (error){
				break;
			}
		}

上面的for循环,意思是如果check(i, j )返回正确的话,就记录flag = 1,并且染色,等到下次再遇到"#"时,如果flag = 1的话就意味着之前出现过一个check正确的了,所以就会error。
但问题是,我这份代码默认了check正确在前,error在后。但也有可能是error在前,check正确在后的呢?所以这个应该在一个for里check,染色之后,再另外一个for判断有没有error。

合作问题

这是团队赛方面的。

  1. 如果可以的话一定要想多几组样例,每个分支都要测试一下。
  2. 跟队友解释代码有助于发现错误。

初始化最大最小值

最大值初始化为-1e18,最小值初始化为1e18。
正无穷也得开到1e18,之前有一道dijkstra算法,就是因为正无穷开得不够大。
最大值千万别初始化为0,当然如果所有数都是整数的话这样子是可以的,不过直接开-1e18

取模的加法不要写错

一次写矩阵乘法的时候犯了一个错误
应该是a = (a + b) % mod; 而不是a += b % mod;这两种写法不一样的,前者可以保证a始终在mod范围内,而后者不是!

错误代码:

Matrix multiply(Matrix a, Matrix b){
    Matrix res;
    for (int i = 0; i <= 1; i++){
        for (int j = 0; j <= 1; j++){
            for (int k = 0; k <= 1; k++){
                res.a[i][j] += (a.a[i][k] * b.a[k][j]) % mod;
            }
        }
    }
    return res;
}

正确代码

Matrix multiply(Matrix a, Matrix b){
    Matrix res;
    for (int i = 0; i <= 1; i++){
        for (int j = 0; j <= 1; j++){
            for (int k = 0; k <= 1; k++){
                res.a[i][j] = (res.a[i][j] + a.a[i][k] * b.a[k][j]) % mod;
            }
        }
    }
    return res;
}

你可能感兴趣的:(算法竞赛)