到网上搜了下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; }
时间: 2024-12-24 23:25:35