造数据时的快速生成方法

来源:互联网 发布:洁厕剂的知乎 编辑:程序博客网 时间:2024/05/22 12:18

    最近Z老师要求出题目,出题目可以分为以下几步:

1.写体面

2.造数据  写标程

3.检测一下  写个说明

这篇文章就造数据这个过程来谢谢我的感悟并分享一些技巧

那这道分块题为例

 

分块入门4(blocks_4.cpp)

时间限制:1s   内存限制:256M

Description

给定一个长为n的序列,要求支持m次下列操作

1.区间加法,即对一段区间内的数整体加上一个数val

2.区间求和,即输出一段区间内的数的和

Input

*第一行:两个整数N,M

*第二行:N个整数,a[i]表示原数列中的第i个数

*第3~m+2行:每行格式如下:ADD x y val 或 SUM x y

Output

对于每一行询问,输出第x个数到第y个数之间的数的和

Sample Input

10 5

1 2 3 4 5 6 7 8 9 10

ADD 1 5 3

SUM 6 2

ADD 4 7 2

ADD 2 6 1

SUM 1 10

Sample Output

32

83

数据范围

50%的数据1<=N,M<=10000,

100%的数据,1<=N,M<=100000,1<=x,y<=N, 0<=val,A[i]<=100000

x不一定<=y,记得使用scanf,printf.

Source

http://hzwer.com/8053.html

 

我们有了这样一个造数据的过程:

void make_data(int n,int m,int min_val,int max_val,int min_range){int seed=time(NULL); srand(seed);printf("%d %d\n",n,m);for (int i=1;i<n;i++)printf("%d ",random(min_val,max_val));printf("%d\n",random(min_val,max_val));while (m){int z=random(0,1);int x,y,val;if (z==0){x=random(1,n); y=random(1,n);while (Abs(x,y)<min_range)x=random(1,n); y=random(1,n);val=random(min_val,max_val);printf("ADD %d %d %d\n",x,y,val);m--;}else if (z==1){x=random(1,n); y=random(1,n);while (Abs(x,y)<min_range)x=random(1,n); y=random(1,n);printf("SUM %d %d\n",x,y);m--;}}}

有了这个过程我们就要去生成10个.in文件

难道我们要一个一个生成吗?

不!(我们要学会偷懒)

注意到c++中freopen 函数中的文件名是一个字符串

我们是不是可以不像往常一样用一个字符串字面量来表示文件名,而是用一个字符串变量来表示文件名,这样我们就可以用for循环来快速生成了。

有了想法后,发现hk同志已经实现了这个偷懒的方法,就要来代码研究了一下


就有了下面的代码:

int main(){for (int i=0;i<10;i++){char name[10];name[0]=i+'0'; name[1]='.'; name[2]='i'; name[3]='n';freopen(name,"w",stdout);if (i<5) make_data(10000,10000,50000,100000,1000);else make_data(100000,100000,80000,100000,10000);fclose(stdout);}return 0;}

注意到这里的十个文件是0~~9.in

这是为什么呐?

因为ASCII码中只有字符’0’~~’9’ 啊

所以在这里就不用1~~10.in 了,毕竟为了方便

 

造十个数据的方法到这里就结束了

但是我们就是要1~~10.in 文件呢,或者说我们要造100组数据该怎么办呢?

其实也很简单,因为只是多了几个字符而已,所以写个过程生成文件名就ok了

void make_name(int k,char name[]){int num[10],len=0;memset(name,0,sizeof(name));if (k==0){name[0]='0'; name[1]='.';name[2]='i'; name[3]='n';return;}while (k){num[++len]=k%10;k/=10;}for (int i=len;i>0;i--)name[len-i]=num[i]+'0';name[len]='.'; name[len+1]='i'; name[len+2]='n'; name[len+3]='\0';}

最后,就是根据标程生成.out文件时也可以用类似方法

这样就再也不用一次次生成了!


当然这种方法比较简陋,还有很多高大上的方法,比如bat批处理,或者string类型中的一些函数都可以快速完成转换,之后我会再写一篇文章介绍的。



原创粉丝点击