在做算法类竞赛的题目的时候,容易想到一个朴素的能保证完全正确的算法,但是会超时。而高效的算法又不能保证完全写对。这时候可以自己写一个朴素的算法、一个数据生成程序和一个文件比较程序进行验证高效算法的正确性。
在Windows下,fc命令提供了比较文件的功能,虽然批处理不如Linux下的bash等强大,但也足以写个自动比较的程序了。
随机数据的产生------C++ rand()用法:
rand()不需要参数,它会返回一个从0到最大随机数的任意整数,最大随机数的大小通常是固定的一个大整数。 这样,如果你要产生0~10的10个整数,可以表达为:
int N = rand() % 11;
这样,N的值就是一个0~10的随机数,如果要产生1~10,则是这样:
int N = 1 + rand() % 10;
总结来说,可以表示为:
a + rand() % n
其中的a是起始值,n是整数的范围。 a + rand() % (b-a+1) 就表示 a~b之间的一个随机数若要0~1的小数,则可以先取得0~10的整数,然后均除以10即可得到随机到十分位的10个随机小数,若要得到随机到百分位的随机小数,则需要先得到0~100的10个整数,然后均除以100,其它情况依此类推。
通常rand()产生的随机数在每次运行的时候都是与上一次相同的,这是有意这样设计的,是为了便于程序的调试。若要产生每次不同的随机数,可以包含time.h头文件,然后使用srand((unsigned)time(NULL))来使用当前时间使随机数发生器随机化,这样就可以保证每两次运行时可以得到不同的随机数序列。
另外,在程序中只要写一次srand((unsigned)time(NULL)),多写会出错;第一次产生随机数后,又写了一遍srand((unsigned)time(NULL)); 相当于根据时间又埋下了种子,而这次埋下的种子和上一次的种子是完全相同的,所以产生的序列也相同,于是计算机又按顺序从头开始把这条序列中的值取出来,产生了上述结果;
其次,rand()好像产生的随机数好像最大也就几万。那么如何产生几亿的大随机数呢?
rand()*rand()是不对的,这样的概率是不一样的。正确的取大随机数的方法是rand1() << n | rand2();即先产生个几万的数,把这个数在二进制下左移,再加上第二次随机生成的数就可以生成高位随机数了~~~
一个简单的随机数据生成器:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <ctime> 5 6 using namespace std; 7 8 int main() 9 { 10 srand(time(0)); 11 int t=0; 12 t=rand()%100; 13 cout<<t<<endl; 14 while(t--) 15 { 16 int n=0; 17 n=10000; 18 cout<<n<<endl; 19 for (int i=1;i<=n;i++) 20 { 21 int a=0,b=0; 22 a=(rand()%10000000)<<8 | (rand()%10000000); 23 b=(rand()%10000000)<<8 | (rand()%10000000); 24 if (a>b) 25 { 26 int temp=b; 27 b=a; 28 a=temp; 29 } 30 cout<<a<<" "<<b<<endl; 31 } 32 33 } 34 return 0; 35 }
批处理对拍程序:
1 :loop 2 make.exe > data.txt //make.exe是随机数据生成器程序 3 standard.exe < data.txt > std.txt //standard.exe标程程序 4 overtaking.exe < data.txt > ans.txt //overtaking.exe自己的程序 5 fc /A std.txt ans.txt 6 if not errorlevel 1 goto loop 7 pause
8 :end
命令行界面会不断提示找不到文件差异,然后就可以放心提交了,当然前提是你朴素的算法写对了。