zoukankan      html  css  js  c++  java
  • 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<<"
    ";
    	}
    	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<<"
    ";
    	}
    	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<<"
    ";
    }
    

    有时候面对的是一个数组,需要使用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] << "
    ";
    	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<<"
    ";
        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<<"
    ";
                for(int i=0;i<n;i++)
                a[i][m]=0,cout<<a[i]<<"
    ";
                //成功了就可以少构造一组了
                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的使用者对你表示感谢。

  • 相关阅读:
    HDU 4864 Task(经典贪心)
    51Nod
    POJ 3122 Pie(二分+贪心)
    HDU 1053 Entropy(哈夫曼编码 贪心+优先队列)
    POJ 1328 Radar Installation(很新颖的贪心,区间贪心)
    11572
    HDU 1789 Doing Homework again(非常经典的贪心)
    合并果子(贪心+优先队列)
    CSU-ACM2018暑假集训6—BFS
    HDU 2102 A计划(两层地图加时间限制加传送门的bfs)
  • 原文地址:https://www.cnblogs.com/BobHuang/p/12749822.html
Copyright © 2011-2022 走看看