在做算法类竞赛的题目的时候,容易想到一个朴素的能保证完全正确的算法,但是会超时。而高效的算法又不能保证完全写对。这时候可以自己写一个朴素的算法、一个数据生成程序和一个文件比较程序进行验证高效算法的正确性。

 

在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


 

命令行界面会不断提示找不到文件差异,然后就可以放心提交了,当然前提是你朴素的算法写对了。

 


举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG