最近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
我们有了这样一个造数据的过程:
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类型中的一些函数都可以快速完成转换,之后我会再写一篇文章介绍的。