到网上搜了下ACM题目产生方法,却没有搜索到有用的资料,那只能自己钻研一下了,下面把钻研出的结果给大家分享一下。
我们知道,ACM的题目对算法要求很高,OJ上而如何评判一个算法的复杂度靠的是测试数据。一般地,题目需要数据量比较大,不可能人工地去产生,只能借助计算机产生测试数据,而为了避免数据出现规律性,那应该尽量让数据随机。接下来,我们就研究最一般的问题,如何产生int,long long ,大整数,以及字符串?
我们知道,C语言提供了我们一个随机函数rand(),可惜的是它只能产生(1~2^15-1)以内的数据。远远满足不了我们对int 型数据的需求(-2^31,2^31-1),更不用说long long 型和大整数了。
那么一种办法是利用 x=rand()/(2^15-1)*(2^31-1),这样做的结果范围是变大了,但是导致有些数根本不会出现,例如rand()等于0的时候,x=0,当rand()等于1的时候,x=(2^31-1)/(2^15-1)所以会导致(0,(2^31-1)/(2^15-1))之间的数根本不会出现。
下面利用了一种简单的算法产生随机数
由于最后产生的数据都要存入文本文档,所以以字符串表示的整数和以int型表示存进去没有差别,这里统一以字符串形式存入文本文档。
1.先随机产生一个数字n,代表即将产生一个n位数
2.对于这个n位数,每位上的数字都随机产生
这样就可以实现构造一个int型数了。
下面是随机产生int型数据的代码
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#include<fstream>
#define digit 10
using namespace std;
string LLMax="9223372036854775807";
string IntMax="2147483647";
string RandomInt()
{
int n=rand()%digit+1;//接下来生成n位数
string s;
if(n==digit)//特殊处理,因为int型要在[-2^31,2^31-1]之内
{
s+=rand()%2+1+'0';
for(int i=1;i<n;i++)
{
int temp=rand()%10;
while(temp>IntMax[i]-'0') temp=rand()%10;
s+=temp+'0';
}
return s;
}
if(n==1) s+=rand()%10+'0';//
else s+=rand()%9+1+'0';//第一位为1-9之间的数
for(int i=2;i<=n;i++) s+=rand()%10+'0';//随机产生第2-n位上的数字
if(rand()%2==1) s='-'+s;//产生负数
return s;
}
int main()
{
int m=0;
ofstream in("int_in.txt");
srand((unsigned)time(NULL));
for(int i=0;i<100;i++)
in<<RandomInt()<<endl;
return 0;
}
同理可以产生 long long型的
代码如下
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#define digit 19
using namespace std;
string LLMax="9223372036854775807";
string IntMax="2147483647";
string RandomLL()
{
int n=rand()%digit+1;//接下来生成n位数
string s;
if(n==digit)//特殊处理,因为int型要在[-2^63,2^63-1]之内
{
s+=rand()%9+1+'0';
for(int i=1;i<n;i++)
{
int temp=rand()%10;
while(temp>LLMax[i]-'0') temp=rand()%10;
s+=temp+'0';
}
return s;
}
if(n==1) s+=rand()%10+'0';//
else s+=rand()%9+1+'0';//第一位为1-9之间的数
for(int i=2;i<=n;i++) s+=rand()%10+'0';//随机产生第2-n位上的数字
if(rand()%2==1) s='-'+s;//产生负数
return s;
}
int main()
{
int m=0;
srand((unsigned)time(NULL));
for(int i=0;i<100;i++)
cout<<RandomLL()<<endl;
return 0;
}
产生大整数
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#include<fstream>
#define digit 100
using namespace std;
string LLMax="9223372036854775807";
string IntMax="2147483647";
string RandomBigInteger()
{
int n=rand()%digit+1;//接下来生成n位数
string s;
if(n==1) s+=rand()%10+'0';//
else s+=rand()%9+1+'0';//第一位为1-9之间的数
for(int i=2;i<=n;i++) s+=rand()%10+'0';//随机产生第2-n位上的数字
//if(rand()%2==1) s='-'+s;//产生负数
return s;
}
int main()
{
int m=0;
ofstream in("in.txt");
srand((unsigned)time(NULL));
for(int i=0;i<100;i++)
in<<RandomBigInteger()<<endl;
return 0;
}
产生字符串
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#define digit 30
using namespace std;
string LLMax="9223372036854775807";
string IntMax="2147483647";
string SmellAlphabet="abcdefghijklmnopqrstuvwxyz";
string UpperAlphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string RandomString()
{
int n=rand()%digit+1;//接下来生成n位字符串
string s;
for(int i=0;i<n;i++) s+=SmellAlphabet[rand()%26];//随机产生字符串
return s;
}
int main()
{
int m=0;
srand((unsigned)time(NULL));
for(int i=0;i<100;i++)
cout<<RandomString()<<endl;
return 0;
}