保研考研机试攻略(满分篇):第一章——技巧之巅(2)

🍦🍦🍦今天我们继续来看第一章的后半部分:考试最佳策略、预处理与打表技巧、对数器技巧等内容。加油!fighting!( •̀ ω •́ )✧

目录

🧊🧊🧊1.4 考试最佳策略

提前准备

开考前

考试中

小数据暴力、大数据随机

🧊🧊🧊1.5 预处理与打表技巧

预处理

一般打表技巧

打表找规律

🥥练习题目:

DreamJudge 1488 数字填充

🧊🧊🧊1.6 对数器技巧


🧊🧊🧊1.4 考试最佳策略

提前准备

1、算法模板一定要提前准备好,不管是单独打印还是记录在书上。

2、算法模板一定要验证它的正确性,在验证的过程中也知道了该如何使用。

3、手机调成静音模式,最好再开一个飞行模式,不要上交以备不时之需。

注意,有的学校要求不允许带任何纸质资料,这种情况下只能大家自己多练习多记忆了!

开考前

1、验证鼠标键盘是否可用,如果不可用及时向老师反应,更换电脑。

2、验证 IDE(如:codeblocks)是否可用,如果不可用及时向老师反应,更换电脑。

3、可以提前将多道题的文件都创建好,一道题卡住了就写下一道。

考试中

1、机试中的题目难度不是从简单到难,难度是随机的,所以刚开始一定要将所有题目都看一遍。

2、找到你认为最简的那道题开始做,记住,一定要从最简单的题目开始做。

3、考试过程中要注意看排行榜,通过人数最多的题目一般都是最简单的题目。

4、当无法通过一个题的时候,先看看有没有其他能做的题,如果也没有其他题能做了,这个时候你就可以使用很多特殊的办法,首先,你一定要相信,机试的数据一定不够强。一般情况下,机试的判题数据都会找学生帮忙生成,往往强度就不会很高

5、不要被题目的数据范围吓到,有可能后台都是小数据,没有更好的解法的时候一定要试试暴力。

6、我们往往被卡都是因为算法不够优秀导致超时,一方面我们可以强行优化输入输出加速来看看能不能水过去。另一方面可以采用小数据暴力,大数据随机的思想来解决问题。

小数据暴力、大数据随机

原理:由于大数据出多组容易导致判题很慢,所以往往不会有很多组。另外对于特殊的数据可能需要手动构造,大数据构造起来麻烦,还要自己构思生成数据的代码。所以一般都是用小数据来验证算法正确性,再加上两组大数组验证算法复杂度。

比如说背包问题:

我们背包问题一般使用动态规划来解,但是你不会怎么办?

那么我们就可以小数据暴力搜索,大数据直接贪心。对于数据不够强的题就能水过去。

🧊🧊🧊1.5 预处理与打表技巧

预处理

预处理是指将答案提前处理好然后再进行查询的方法。

什么时候会用到预处理:查询量特别大的时候。

例题

我们要查询斐波那契数列的第 n 项,n(n < 10000)。并且我们要查询 10 万次。

错误的超时解法:

#include<bits/stdc++.h>
using namespace std;
int f[10005];
int main(){
    int t;
    scanf("%d", &t);//查询次数
    while (t--) {
        int n;
        scanf("%d", &n);//查询第 k 项
        f[1] = 1;
        f[2] = 1;
        for (int i = 3; i <= n; i++) {
            f[i] = f[i-1] + f[i-2];
        }
        printf("%d\n", f[n]);
    }
    return 0;
}

超时分析:每一次查询,我们都递推了一遍斐波那契数列,如果每一次查询的都是最后一项。那么最坏情况就是:100000*10000,必然是会超时的。

正确的预处理解法:

#include<bits/stdc++.h>
using namespace std;
int f[10005];
int main(){
    f[1] = 1;
    f[2] = 1;
    for (int i = 3; i <= 10000; i++) {
        f[i] = f[i-1] + f[i-2];
    }
    int t;
    scanf("%d", &t);//查询次数
    while (t--) {
        int n;
        scanf("%d", &n);//查询第 k 项
        printf("%d\n", f[n]);
    }
    return 0;
}

可以发现两段代码惊人的相似,有什么区别呢?

区别在于下面的代码只会递推一遍斐波那契数列,然后将所有的答案都存储于 f 数组中。

一般打表技巧

打表是指我们提前使用暴力的方法,将答案记录下来写到纸上或代码中,然后再根据题目的实际需求去直接输出提前记录好的答案。

例题

求一个数 x 的 100000000 次方模 2333 的值是多少。x 的范围是(1<= x <=10)

解析:这个时候我们如果不会二分快速幂的话,可以直接用一个暴力的代码将 1 到 10 的答案分别求出来,可能要等上几分钟,然后直接判断输入的值对应输出结果即可。

打表找规律

在一些可能存在规律的问题中,我们可以通过暴力打表求出前几十项的值,发现其中的规律,从而帮助我们解出该题。

例题

输入一个整数 a(a<10^9),b 可以取任意值,求 a%b 的可能产生多少种不同的结果。

解析:乍一看,我们一脸懵逼。这个时候你只要去打表分析,首先 b 大于 a 就重复了,那么我们只需要对于任意一个 a,去枚举 b 的值,看 a%b 会产生多少种不同的结果即可。通过打表分析,你会发现:当 a = 1 时,结果 ans = 1,当 a 为偶数时,ans = a / 2 + 1,当 a 为奇数时,ans = a / 2 + 2。

🥥练习题目:

DreamJudge 1488 数字填充

 

#include<bits/stdc++.h>
using namespace std;
int main()
{
	string a[10][5];
    a[0][0]="111";
    a[0][1]="101";
    a[0][2]="101";
    a[0][3]="101";
    a[0][4]="111";

    a[1][0]="001";
    a[1][1]="001";
    a[1][2]="001";
    a[1][3]="001";
    a[1][4]="001";

    a[2][0]="111";
    a[2][1]="001";
    a[2][2]="111";
    a[2][3]="100";
    a[2][4]="111";

    a[3][0]="111";
    a[3][1]="001";
    a[3][2]="111";
    a[3][3]="001";
    a[3][4]="111";

    a[4][0]="101";
    a[4][1]="101";
    a[4][2]="111";
    a[4][3]="001";
    a[4][4]="001";

    a[5][0]="111";
    a[5][1]="100";
    a[5][2]="111";
    a[5][3]="001";
    a[5][4]="111";

    a[6][0]="111";
    a[6][1]="100";
    a[6][2]="111";
    a[6][3]="101";
    a[6][4]="111";

    a[7][0]="111";
    a[7][1]="001";
    a[7][2]="001";
    a[7][3]="001";
    a[7][4]="001";

    a[8][0]="111";
    a[8][1]="101";
    a[8][2]="111";
    a[8][3]="101";
    a[8][4]="111";

    a[9][0]="111";
    a[9][1]="101";
    a[9][2]="111";
    a[9][3]="001";
    a[9][4]="111";
    string s;
    cin>>s;
    int len=s.size();
    int b[100];
    for(int i=0;i<len;i++) b[i]=s[i]-'0';
    for(int i=0;i<5;i++)
	{
        for(int j=0;j<len;j++) cout<<a[b[j]][i];
        cout<<endl;
    }
	return 0;
}

🧊🧊🧊1.6 对数器技巧

这一节主要是为了解决下述情况的问题:题目做半天还是错,看起来和别人的代码也差不多,就是不知道错在哪了,而且反馈错误数据也是成千上万行,根本没法去对比……

使用对数器进行对拍,可以快速的找到的你的代码错误所在。

简单说,就是将你的代码和正确的代码放在一起,然后随机生成一些符合题目的要求的数据,然后比较你的代码的输出结果和正确代码的输出结果是否一致,从而来验证你的代码的正确性。

当然,随机的数据越多,正确性也就越高。

我们举个排序的例子来看怎么用对数器:

我自己写了一个排序的算法,但是我不知道我写的这个排序算法到底有没有问题,但是我拿到别人的正确的排序的算法代码,我如何比较呢?

我的代码:

for (int i = 1; i <= n; i++)
    for (int j = 1; j < n; j++)
        if (b[j] > b[j+1])
            swap(b[j], b[j+1]);

正确的:

sort(c+1, c+n+1);

对数器使用模板:

#include <bits/stdc++.h>
using namespace std;
struct node {
    int a[105];//随机的数
    int b[105];//我的方法排序后的数
    int c[105];//正确的方法排序后的数
    int n;
    // 按照题意随机一些输入数据
    void Rand() {
        n = rand()%100 + 1;
        for (int i = 1; i <= n; i++)
            a[i] = rand()%10000;
    }
    // 使用我的解法得到的答案
    void My_method() {
        for (int i = 1; i <= n; i++)
            b[i] = a[i];
        for (int i = 1; i <= n; i++)
            for (int j = 1; j < n; j++)
                if (b[j] > b[j+1])
                    swap(b[j], b[j+1]);
    }
    // 使用其他正确的解法得到的答案
    void Right_method() {
        for (int i = 1; i <= n; i++)
            c[i] = a[i];
        sort(c+1, c+n+1);
    }
    // 比较我的答案和正确答案是否一致
    // 如果不一致输出测试数据然后分析
    int Check() {
        for (int i = 1; i <= n; i++) {
            if (b[i] != c[i]) {
                printf("my code is error!\n");
                printf("the test data:\n");
                for (int j = 1; j <= n; j++) {
                    printf("%d ", a[j]);
                }
                printf("\n");
                return 1;
            }
        }
        return 0;
    }
};

int main() {
    srand(time(NULL));//将时间作为随机种子
    int t = 100;//样本大小
    while (t--) {
        node code;
        code.Rand();
        code.My_method();
        code.Right_method();
        if (code.Check()) return 0;
    }
    printf("my code is right!\n");
}

代码分析:首先随机 100 组输入数据,然后使用自己的算法去跑出结果,然后使用正确的算法去跑出结果,最后比较两个结果是否一致,如果不一致就输出是哪一组数据导致的结果不一致,最后分析自己的算法问题所在。

 

 

创作不易,点个赞吧~点赞收藏不迷路,感兴趣的宝子们欢迎关注该专栏~

勤奋努力的宝子们,学习辛苦了!宝子们可以收藏起来慢慢学哦~🌷🌷🌷休息下,我们下部分再见👋( •̀ ω •́ )✧~

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值