出题日记
2024-03-13 12:16:51 # OI # Problem

参考文章:
#Article01
#Article02

个人库的引用

cpp文件放至同库文件夹内,然后:

#include"******"

注意个人库用双引号引用,标准库用<>引用

主函数带参

正常我们写主函数都是这样的:

int main()

而今天我却看到这样一种写法:

int main(int argc,char* argv[])

当然,这也等同于:

int main(int argc,char** argv)

其中,qrgv储存的是一个字符串指针的数组,也就是说它里面存着是一堆字符串,那么这些字符串存的是什么呢?argc里存的又是什么整数呢?

我们不妨试一试:

#include "testlib.h"
#include<bits/stdc++.h>
using namespace std;
int main(int argc,char* argv[])
{
    printf("%d\n",argc);
    for(int i=0;i<argc;i++)
        printf("%s\n",argv[i]);
    return 0;
}

image.png

看来,argc代表的就是传入参数的个数,而argv[]中存的就是每一个参数(以字符串的形式)。

我们调用该程序时引用的相对路径也以绝对路径的形式呈现了出来,并作为第一个参数。

类似于ping ***.***.*.*之类的命令,这些命令在启动对应程序的同时便已传入参数,而不是启动后的输入。

当然,这些变量名(argc argv)也是可以自己更改的。

初始化checker

void registerTestlibCmd(argc, argv)

该函数在一开始必须调用一次。

编写checker

checker的编写除了输入和输出其实大部分都和正常代码一样的。

详情见

举个例子:

#include "testlib.h"
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7;
int n,k,kk;
int a[N],b[N];
struct mon{
    int a,b,id;
}m[N];
int iop;
int x,y,z;
string s,ss;
char poans[20];
int main(int argc,char* argv[])
{
    registerTestlibCmd(argc, argv);
    n=inf.readInt();
    k=inf.readInt();
    for(int i=1;i<=n;i++)
    {
        m[i].a=inf.readInt();
        m[i].b=inf.readInt();
        m[i].id=i;
    }
    ss=ouf.readToken();//读入选手输出Yes/No
    if(ss=="Yes")
    {
        kk=ouf.readInt();//读入剩余血量
        for(int i=1;i<=n;i++)
        {
            int p=ouf.readInt();
            k+=m[p].b-m[p].a;
            if(k<0)
            {
                ss="No";
                break;
            }
        }
    }
    
    s=ans.readToken();
    if(s=="Yes") k=ans.readInt();
    if(s==ss&&s=="Yes")
    {
        if(k==kk) quitf(_ok, "The answer is correct.");
        else quitp(0.5,"Partially Correct get %d percent", 50);
    }
    else if(s==ss&&s=="No") quitf(_ok, "The answer is correct.");
    else
    {
        quitf(_wa, "The answer is wrong.");
    }
    return 0;
}

数据生成

这绝对是最闹心的一个环节了。

文件输入输出流见

例子:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5;
const int K=10000;
int times=4;
ofstream infile,outfile;
int n,k;
int a[1000007],b[200007];
struct mon{
    int a,b,id;
}m[200007];
bool cmp(mon x,mon y)
{
    if((x.b-x.a>0)&&(y.b-y.a>0)) return x.a<y.a;
    else if(x.b-x.a>0) return true;
    else if(y.b-y.a>0) return false;
    return x.b>y.b;
}
void file(int p)
{
    char inname[10];
    char outname[10];
    infile.close();
    outfile.close();
    sprintf(inname,"mon%02d.in",p);
    sprintf(outname,"mon%02d.out",p);
    infile.open(inname);
    outfile.open(outname);
}
void make()
{
    int n=rand()%N+1;
    int op=rand()%K+1;
    int k=rand()%op+1;
    infile<<n<<' '<<k<<endl;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        x=(rand()%op+rand()%k)%op;
        // y=(rand()%op+k/50);
        y=(x+rand()%op-rand()%op+op)%op;
        m[i].a=x,m[i].b=y,m[i].id=i;
        infile<<x<<' '<<y<<endl;
    }
    sort(m+1,m+1+n,cmp);
    int i=1;
    for(;i<=n;i++)
    {
        if(k>=m[i].a)
        {
            if(m[i].b-m[i].a>=0) k+=m[i].b-m[i].a;
            else break;
        }
        else
        {
            outfile<<"No";
            return;
        }
    }
    if(i==n)
    {
        outfile<<"Yes"<<endl;
        return;
    }
    for(;i<=n;i++)
    {
        if(k>=m[i].a)
        {
            k+=m[i].b-m[i].a;
        }
        else
        {
            outfile<<"No";
            return;
        }
    }
    outfile<<"Yes"<<endl;
    outfile<<k<<endl;
    for(int i=1;i<=n;i++)
    {
        outfile<<m[i].id<<' ';
    }
}
int main()
{
    srand(time(0));
    for(int i=32;i<=times+31;i++)
    {
        file(i);
        make();
    }
    infile.close();
    outfile.close();
    return 0;
}

最后

你就可以把这些压缩递交了,也可以设置一些substack之类的。