互相给一巴掌器

对拍器

\(OI\)中,我们常常需要将正解和暴力优势互补,暴力慢,正解的正确性有时懒得证,于是我们干脆直接将它们对比。

但是

一组一组手敲数据真的慢,还不一定查得出来

所以,我们就需要对拍

对拍四要素:

  • 正解
  • 暴力
  • 数据生成器
  • 对拍器

正解、暴力根据题目。

数据生成器:根据题目要求随机生成数据。但是可能造不出\(HACK\)数据

对拍器:将两个程序对比的机器。它的流程为:

  • 生成一组数据
  • 正解、暴力算结果
  • 对比,判断是否一样
  • 重复执行以上过程直到出错

这就要依靠\(<windows.h>\)库中的\(system()\)函数。

代码:

#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
    while(1)
    {
        system("数据生成器.exe > data.txt");
        system("正解.exe < data.txt > yours.txt");
        system("暴力.exe < data.txt > expected.txt");
        if(system("fc expected.txt yours.txt"))   break;
    }
    cout<<"发现错误,请查看!"<<endl;
    system("pause");
    return 0;
}

例如我们要检查\(\text{BigInt A+B}\)的正确性。

数据生成器:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

int main()
{
	srand(time(NULL));
	int a=rand();
	int b=rand();
	cout<<(int)a<<" "<<(int)b;
}

两个程序:

#include<iostream>
using namespace std;

int main()
{
	int a,b;
	cin>>a>>b;
	cout<<a+b<<endl;
}
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 1005;
struct bigint
{
    int len,s[N];
    bigint()  {  memset(s,0,sizeof(s));  len=1;  }
    bigint(int num)  {  *this=num; }
    bigint(char *num) { *this=num; }
    bigint operator =(int num)
    {
        char c[N];
        sprintf(c,"%d",num);
        *this=c;
        return *this;
    }
    bigint operator =(const char *num)
    {
        len=strlen(num);
        for (int i=0;i<len;i++) s[i]=num[len-1-i]-'0';
        return *this;
    }
    string str()
    {
        string res="";
        for (int i=0;i<len;i++) res=(char)(s[i]+'0')+res;
        return res;
    }
    void clean()
    {
        while (len>1&&!s[len-1]) len--;
    }
    bigint operator +(const bigint &b)
    {
        bigint c;    
        c.len=0;
        for (int i=0,g=0;g||i<len||i<b.len;i++)
        {
            int x=g;
            if (i<len) x+=s[i];
            if (i<b.len) x+=b.s[i];
            c.s[c.len++]=x%10;
            g=x/10;
        }
        return c;
    }
    bigint operator -(const bigint &b)
    {
        bigint c;
        c.len=0;
        int x;     
        for (int i=0,g=0;i<len;i++)
        {
            x=s[i]-g;
            if (i<b.len) x-=b.s[i];
            if (x>=0) g=0;
            else{          
                x+=10;
                g=1;
            };
            c.s[c.len++]=x;
        }
        c.clean();
        return c;
    }
    bigint operator *(const bigint &b)
    {
        bigint c;
        c.len=len+b.len;
        for (int i=0;i<len;i++) for (int j=0;j<b.len;j++) c.s[i+j]+=s[i]*b.s[j];
        for (int i=0;i<c.len-1;i++) { c.s[i+1]+=c.s[i]/10; c.s[i]%=10; }
        c.clean();
        return c;  
    }
    bool operator <(const bigint &b)
    {
        if (len!=b.len) return len<b.len;
        for (int i=len-1;i>=0;i--)
             if (s[i]!=b.s[i]) return s[i]<b.s[i];
        return false;
    }
    bigint operator +=(const bigint &b)
    {
        *this=*this+b;
        return *this;
    }
    bigint operator -=(const bigint &b)
    {
        *this=*this-b;
        return *this;
    }  
};
istream& operator >>(istream &in,bigint &x)
{
  string s;
  in>>s;
  x=s.c_str();
  return in;
}
ostream& operator <<(ostream &out,bigint &x)
{
    out<<x.str();
    return out;
}
int main()
{
    bigint a,b,c;
    ios::sync_with_stdio(false);
    cin>>a>>b;
//    cout<<a<<endl;
//    cout<<b<<endl;
    c=a+b;
    cout<<c<<endl;
    return 0;
}

对拍器:

#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
	int T=0;
    while(1)
    {
    	T++;
    	cout<<"testdata<"<<T<<">"<<endl;
        system("datamaker.exe > data.txt");
        system("A+B.exe < data.txt > yours.txt");
        system("A+B_1.exe < data.txt > expected.txt");
        if(system("fc expected.txt yours.txt")) return 0;
    }
    return 0;
}

如果没有错,运行下来是这样的:

我们把\(BigInt\)的输出改为:cout<<a+b+rand()%2;

考验\(rp\)的时候到了。

事实证明我还是太非了,才五组就挂了。

posted @ 2019-04-30 16:26  神威无敌大蒟蒻  阅读(199)  评论(2编辑  收藏  举报