OI赛制对拍代码(蓝桥杯对拍代码)(两种方法)

OI赛制对拍代码(蓝桥杯对拍代码)

视频讲解链接:Codeforces讲解他来了?蓝桥杯备战技巧之对拍器_哔哩哔哩_bilibili

先写题目的一个优化代码,当不知道是否正确的时候,可以写一个暴力代码(必须保证正确),否则两个代码比较毫无意义,之后再写一个构造随机数据的代码。最后将构造的随机数据传入优化代码和暴力代码中运行,看结果是否正确。

以01背包为例:优化代码是DP,暴力代码用DFS实现:

优化代码DP:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

int n, m;
int f[N];

int main()
{
    ///输入重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
    freopen("input.txt", "r", stdin);

    ///输出重定向,将stdout的内容以写的方式写给 文件 DP.txt ,此时会创建一个 DP.txt 文件
    freopen("DP.txt", "w", stdout);

    ///这相当于读input.txt文件的内容到m,n中
    cin >> n >> m;

    for (int i = 1; i <= n; i ++ )
    {
        int v, w;
        cin >> v >> w;
        for (int j = m; j >= v; j -- )
            f[j] = max(f[j], f[j - v] + w);
    }

    ///将f[m] 的内容写到 DP.txt文件中
    cout << f[m] << endl;
    return 0;
}

暴力代码DFS:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

int n, m;
int v[N], w[N];
int ans;

void dfs(int u, int sum, int value)
{
    if (u == n) ans = max(ans, value);
    else
    {
        dfs(u + 1, sum, value);

        if (sum + v[u] <= m)
            dfs(u + 1, sum + v[u], value + w[u]);
    }
}

int main()
{
    ///输入重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
    freopen("input.txt", "r", stdin);

    ///输出重定向,将stdout的内容以写的方式写给 文件 DFS.txt ,此时会创建一个 DFS.txt 文件
    freopen("DFS.txt", "w", stdout);

    ///这相当于读input.txt文件的内容到m,n中
    cin >> n >> m;

    for (int i = 0; i < n; i ++ ) cin >> v[i] >> w[i];

    dfs(0, 0, 0);

    ///将ans 的内容写到 DFS.txt文件中
    cout << ans << endl;
    return 0;
}

构造随机生成数据代码:


#include <iostream>
#include <cstring>
#include <algorithm>
#include <fstream>
#include <ctime>

using namespace std;

const int mod = 50;

void create_data()
{
    ///创建一个输入流对象,并且新建一个input.txt文件(如果没有的话),
    ///存在则覆盖,记得后缀加.txt,表示文本文件,别只写input;
    ofstream fout("input.txt");

    int n = (rand() % mod + mod ) % mod;
    int m = (rand() % mod + mod ) % mod;

    ///fout相当于cout,他将得到的n,m值写入input.txt文件中
    fout << n << ' ' << m << endl;

    for(int i=0; i<n; ++i)
    {
        int v = (rand() % mod + mod ) % mod;
        int w = (rand() % mod + mod ) % mod;
        fout << v << ' ' << w << endl;
    }

    fout.close(); ///关闭文件,自动保存文件
}

bool work()
{
    create_data();  ///生成随机数据

    system("DP.exe"); ///执行可执行文件DP
    system("DFS.exe"); ///执行可执行文件DFS

    return system("fc DP.txt DFS.txt");
    ///system("fc 文件一 文件二"); 注意中间不能加逗号隔开,如果文件
    ///相同返回0,不相同返回1
}

int main()
{
    srand(time(0));

    for (int i = 0; i < 100; i ++ )
    {
        if(work())  break;
    }

    return 0;
}

注意,这三个代码要放在同一个文件中,可以在编译器新建一个CPP文件来写随机生成数据代码,然后在此文件下新建两个空文件,用来写DP和DFS,然后保存在该文件夹下。不能在外面新建两个CPP文件,否则执行 system("DP.exe")会出错;

关于如何将输入输出重定向到控制台,也就是我们在IDE上看到的黑框框,这是windows下的操作,在Linux下似乎是不同的命令:

  freopen("CON", "r", stdin);
  freopen("CON", "w", stdout);

 在同一个文件下要新建三个cpp文件,似乎有点麻烦,因此我们可以把DP代码和DFS代码写成两个函数,然后将数据保存到vector中,我在之前也想把结果保存到文件里,然后用文件来进行比较,但是似乎行不通,emm,不知道哪儿有问题。下面给出问题代码:

可以不看:

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

const int mod = 100;
const int N = 1e5+10;
int f[N], v[N], w[N];
int n, m;
int ans = 0;
vector<int> vec1, vec2;

void create_data()
{
    ofstream fout("input.txt");

    int n = (rand() % mod + mod ) % mod;
    int m = (rand() % mod + mod ) % mod;

    fout << n << ' ' << m << endl;

    for(int i=0; i<n; ++i)
    {
        int v = (rand() % mod + mod ) % mod;
        int w = (rand() % mod + mod ) % mod;
        fout << v << ' ' << w << endl;
    }

    fout.close();
}

void DP()
{
    fill(f,f + N, 0);
    ///输入重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
    freopen("input.txt", "r", stdin);

    ///输出重定向,将stdout的内容以写的方式写给 文件 DP.txt ,此时会创建一个 DP.txt 文件
    freopen("DP.txt", "w", stdout);

    ///这相当于读input.txt文件的内容到m,n中
    cin >> n >> m;

    for (int i = 1; i <= n; i ++ )
    {
        int v, w;
        cin >> v >> w;
        for (int j = m; j >= v; j -- )
            f[j] = max(f[j], f[j - v] + w);
    }

    ///将f[m] 的内容写到 DP.txt文件中

   // vec1.push_back(f[m]);

    cout << f[m] << endl;
    fclose(stdout);
    fclose(stdin);
}

void dfs(int u, int sum, int value)
{
    if (u == n) ans = max(ans, value);
    else
    {
        dfs(u + 1, sum, value);

        if (sum + v[u] <= m)
            dfs(u + 1, sum + v[u], value + w[u]);
    }
}

void DFS()
{
    ans = 0;
    ///文件重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
    freopen("input.txt", "r", stdin);

    ///文件重定向,将stdout的内容以写的方式写给 文件 DFS.txt ,此时会创建一个 DFS.txt 文件
    freopen("DFS.txt", "w", stdout);

    ///这相当于读input.txt文件的内容到m,n中
    cin >> n >> m;

    for (int i = 0; i < n; i ++ ) cin >> v[i] >> w[i];

    dfs(0, 0, 0);

    ///将ans 的内容写到 DFS.txt文件中
    //vec2.push_back(ans);
    cout << ans << endl;

    fclose(stdout);
    fclose(stdin);
}

void deal()
{
    int n, m;
    int f[100];

    freopen("input.txt", "r", stdin);
    cin >> n >>  m;
    for(int i=0; i<n; ++i)
        cin >> f[i];
    cout << n << ' ' << m << endl;
    for(int i=0; i<n; ++i)
        cout << f[i] << ' ';
    puts("");
    fclose(stdin);
}


bool work()
{
    create_data();

    deal(); ///所有的deal函数都是测试代码
    DP();
    deal();

    DFS();

    freopen("CON", "r", stdin);
    freopen("CON", "w", stdout);


    ///只会输出“error”,奇怪,搞不懂
    cout << "made" << endl;
    puts("error");
   // deal();
  //  freopen("CON", "r", stdin);
  //  freopen("CON", "w", stdout);

    puts("YES");

    return system("fc DP.txt DFS.txt");
   // return vec1 == vec2;
}

int main()
{
    for(int i=0; i<3; ++i)
    {
        printf("iterator: %d\n", i);

        if(!work()) ;
            break;
    }

    return 0;
}

最后我们再来换个方式,以vector来存储输出数据,因为vector也可以直接比较,相等返回true,否则返回false,也挺方便的:

代码:

/// 2) 以vector来存储输出数据


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

const int mod = 100;
const int N = 1e5+10;
int f[N], v[N], w[N];
int n, m;
int ans = 0;
vector<int> vec1, vec2;

void create_data()
{
    ofstream fout("input.txt");

    int n = (rand() % mod + mod ) % mod;
    int m = (rand() % mod + mod ) % mod;

    fout << n << ' ' << m << endl;

    for(int i=0; i<n; ++i)
    {
        int v = (rand() % mod + mod ) % mod;
        int w = (rand() % mod + mod ) % mod;
        fout << v << ' ' << w << endl;
    }

    fout.close();
}

void DP()
{
    fill(f,f + N, 0);
    ///输入重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
    freopen("input.txt", "r", stdin);

    cin >> n >> m;

    for (int i = 1; i <= n; i ++ )
    {
        int v, w;
        cin >> v >> w;
        for (int j = m; j >= v; j -- )
            f[j] = max(f[j], f[j - v] + w);
    }

    vec1.push_back(f[m]);

    fclose(stdin);
}

void dfs(int u, int sum, int value)
{
    if (u == n) ans = max(ans, value);
    else
    {
        dfs(u + 1, sum, value);

        if (sum + v[u] <= m)
            dfs(u + 1, sum + v[u], value + w[u]);
    }
}

void DFS()
{
    ans = 0;
    ///文件重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
    freopen("input.txt", "r", stdin);

    cin >> n >> m;

    for (int i = 0; i < n; i ++ ) cin >> v[i] >> w[i];

    dfs(0, 0, 0);

    vec2.push_back(ans + 1);

    fclose(stdin);
}

void deal()
{
    int n, m;
    int f[100];

    freopen("input.txt", "r", stdin);
    cin >> n >>  m;
    for(int i=0; i<n; ++i)
        cin >> f[i];
    cout << n << ' ' << m << endl;
    for(int i=0; i<n; ++i)
        cout << f[i] << ' ';
    puts("");
}


bool work()
{
    create_data();

    DP();

    DFS();

    return vec1 == vec2;
}

int main()
{
    bool flag = true;
    for(int i=0; i<5; ++i)
    {
        vec1.erase(vec1.begin(), vec1.end());
        vec2.erase(vec2.begin(), vec2.end());

        printf("iterator: %d\n", i);

        if(!work())
        {
            flag = false;
            break;
        }

        ///以下代码可以不要

        /*
        for(auto ele : vec1)
            cout << ele << ' ';
        puts("");
        for(ele : vec2)
                cout << ele << ' ';
        puts("");
        */

    }

    if(!flag)
    {
        puts("输入:");
        deal();

        puts("错误输出数据:");
        for(auto ele : vec1)
            cout << ele << ' ';
        puts("");
        for(ele : vec2)
                cout << ele << ' ';
        puts("");
    }
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值