造数据时的快速生成方法

    最近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类型中的一些函数都可以快速完成转换,之后我会再写一篇文章介绍的。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值