TZOJ帮助之出题

本博客原文地址:https://www.cnblogs.com/BobHuang/p/12749822.html
如果你已经能够控制自己的代码,且题目数300题以上成为高级用户,欢迎你为TZOJ贡献题目,与他人一起分享AC的快乐。题目通过管理员验证后,系统将赠送20分积分,积分可以用于课程平时分、兑换礼品等。

一、确定题目并撰写题面

首先你需要确定你的题目类型和解题方法,然后就可以书写题目描述了,鼠标滑到导航栏的练习,然后点击上传题目
在这里插入图片描述可以看到如下界面
在这里插入图片描述
点击红色框框里的上传题目,就可以添加题目了。绿色框为待定题目,需要等待系统管理员通过,黄色框为已上传题目列表,表示有人核验了题目后管理员对题目进行了通过。
点击上传题目后会出现如下界面。
在这里插入图片描述
首先是名称,请为你的题目想一个好名字。然后是时间限制(普通/Java)、时间限制(Java)、内存限制、数据输出限制,一般情况保持默认值不需要更改
如果你是算法类题目,时间限制(普通/Java)是你标程的3~7倍,如果你加入了读入优化等nb内容,直接7倍拉满。由于其他语言运行较慢,时间限制(Java)请开时间限制(普通/Java)的3倍,内存限制你自己可以计算下程序需要多少内存,如果要卡内存可以进行修改。如果你的输出比较多,可以修改数据输出限制。
然后依次填写描述、输入、输出、样例输入、样例输出,请保证题目没有歧义,多组数据请在输入里注明。如果需要提示请在提示里填写。也可以限定语言进行代码填空,对学习函数和类等有帮助,教师会用到这个功能。

二、制造数据及提交标程

数据是一个题目的核心,一个强大的数据才代表这个题目是完整的。我们一般会特殊构造几组,并随机多组。在这里主要介绍下使用C++语言来制造数据。
C++ 库有一个名为 rand() 的函数,每次调用该函数都将返回一个非负整数。

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

int main()
{
	//循环随机100次
	for(int i=0;i<100;i++)
	{
		int x=rand();
		cout<<x<<"\n";
	}
	return 0;
}

rand函数返回的数字其实是伪随机数。它们虽然具有随机数的表现和属性,但实际上并不是随机的。它们实际上是用算法生成的。各种各样的伪随机数算法可以了解一下。
我们运行以上代码两次,我们会发现随机到的数字完全相同,该算法需要一个起始值,称为随机数种子,以生成数字。如果没有给出一个种子,那么它每次运行时产生相同的数字流。
我们一般会以时间作为随机数种子time(NULL),其实他是从系统获取的是从1970年1月1日00:00:00到现在为止经过了多少秒,也就是时间戳。时间每分每秒都在流逝,这个已经基本可以满足我们的要求了。在 C++ 中,给定随机数种子是通过调用 srand 函数完成的。所以以上代码可以写为,你就会发现数字不同了。随机也是可以AC题目的,2018上海大都会赛A等你AC

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

int main()
{
	srand(time(NULL));
	//循环随机100次
	for(int i=0;i<100;i++)
	{
		int x=rand();
		cout<<x<<"\n";
	}
	return 0;
}

但是经常我们是需要随机一个区间的,我们可以利用取余生成区间最大值-最小值的值然后加上固定值

#include <bits/stdc++.h>
using namespace std;
int main()
{
	//把当前时间作为随机数种子,没有这一步你的随机是假的
	srand(time(NULL));
	//可以生成[1000,10000)的一个整数
	int n=0;
	while(n<=1000)
	{
		n=rand()%10000;
	}
	//显然上面这个效率很差,特别是区间很小的话,你可以随机一个[0,9000)的数+1000就好了
	n=rand()%9000+1000;
	cout<<n<<"\n";
}

有时候面对的是一个数组,需要使用random_shuffle,以下代码为对[1,20]求出他的一个排列

#include <bits/stdc++.h>
using namespace std;
int main()
{
	srand(time(NULL));
	int a[20], n = 20;
	for (int i = 0; i < n; i++)
		a[i] = i + 1;
	random_shuffle(a, a + n);
	for (int i = 0; i < n; i++)
		cout << a[i] << "\n";
	return 0;
}

这里以TZOJ2624: 避雨 为例,我们来看下如何构造数据。有一个二维数组表示的二维图像记录了s表示shachen和他女朋友的位置以及躲雨的位置,问我们最近的躲雨点坐标(i,j)。
没AC这道题目的先AC它。
我们提交的数据为.in和.out文件,我们可以重定向输入输出流来制造数据。
首先我们需要重定向输出流,我们精心制造的数据保存为.in文件。freopen("data1.in","w",stdout);会存储到这个程序的输出到当前文件夹下的data1.in文件下。这个题目为T组,我们可以定义一个T表示组数,一般选100左右,我选择了50,然后将它输出。然后m和n的大小范围均为[1,9],rand%9是[0,8],+1就是我们所需要的。然后去随机这个图像,这个图像里有三种,分别是'.','s','d',我们可以%3,每个数字一个字符,我是2是s,s只能出现一次,所以我需要插个旗子标记下。随机完成后我们需要检验数据是否合法,合法的话就可以啦。不合法还要重造。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    //所有会被存储到当前文件夹下的data1.in文件下
    freopen("data1.in","w",stdout);
    srand(time(NULL));
    int T=50;
    cout<<T<<"\n";
    while(T)
    {
        //m和n都是[1,9],rand%9是[0,8],+1就是了
        int n=rand()%9+1,m=rand()%9+1;
        //flag用来标记只出现一个s
        int flag=0;
        string a[11];
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                //x的值为[0,2]
                int x=rand()%3;
                //随机出2就是s,但是只能有一个
                if(x==1)
                a[i]+="d";
                else if(x==2&&flag==0)
                a[i]+="s",flag=1;
                else 
                a[i]+=".";
            }
        }
        //用来检验是否合法
        int flag1=0,flag2=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(a[i][j]=='s')
                {
                    flag1++;
                }
                if(a[i][j]=='d')
                {
                    flag2++;
                }
            }
        }
        //'s'只能有一个,d存在
        if(flag1==1&&flag2)
        {
            //输出当前的n和m以及当前构造的数据
            cout<<n<<" "<<m<<"\n";
            for(int i=0;i<n;i++)
            a[i][m]=0,cout<<a[i]<<"\n";
            //成功了就可以少构造一组了
            T--;
        }
    }
    return 0;
}

然后写出你的标程,也就是标准程序。

    freopen("data1.in","r",stdin);
    freopen("data1.out","w",stdout);

在代码的最上两行输入以上代码,表示以data1.in作为输入流,对文件进行读取,以data1.out作为输出流,对文件进行写入。然后可以跑出data1.out这个文件。
接下来我们要把自己的数据上传到平台上,回到上传题目首页,在相应题目下点击添加即可,把自己刚才的.in和.out都上传到平台上去,然后返回点击查看,确保每个数据都上传成功。
然后将自己标程代码提交到平台上,注意注释掉freopen的两行代码。如果AC,这个题目你的部分就基本完成,等待管理员通过就可以了,如果题目有问题(数据出错、题意不清等)管理员会联系你进行修改。
TZOJ还支持Special Judge,即有些题目会显示红色的Special Judge提示,表示选手的输出不一定要和你的相同,如果需要这个功能,请联系管理员。

三、管理员通过

你的题目经过别人的验证后,经过一段时间管理员会对你的题目进行通过,即你的题目会被显示在题库里。这道题目就会进入已上传题目列表,你也将获得20积分奖励。非常感谢你丰富TZOJ的题库,在这里我代表所有TZOJ的使用者对你表示感谢。

posted @ 2020-04-22 09:25  暴力都不会的蒟蒻  阅读(147)  评论(0编辑  收藏