模拟题5

题目描述

  差为2的两个素数被称为孪生素数对,例如3和5, 11和13.
  给定一个区间,请输出区间内所有的孪生素数对.
输入格式
  两个正整数a,b,其中a<b,以空格分开
输出格式
  区间[a,b]内的所有孪生素数对,按从小到大顺序。每行一个素数对,其中小的在前,大的在后,以空格分开。
  如果区间内没有素数对的话,输出-1.
样例输入
2 15
样例输出
3 5
5 7
11 13
样例输入
14 18
样例输出

-1

 http://www.cnblogs.com/skysun

很水的一道题,暴力可以过(直接从2到sqrt(n)来判断n是不是素数)

但是我不是只想过一道题而已

学习了一下非递归的二分,复习了一遍打表

非递归二分:

当要找数组里第一个大于等于w的元素时

k:=midfind(l,r+1,w),这里r+1是非常亮的一个地方

就是当l到r这个区间没有合法值时,会到r+1 这个位置,

便于进行人工判断处理

其实递归二分也可以这么打,

今天打了一下非递归的,感觉不错

代码如下:

View Code
 1 program sky;
2 var
3 i,j,tot,n : longint;
4 k,x,y : longint;
5 bj : boolean;
6 a : array[0..100000] of longint;
7 v : array[0..1000001] of boolean;
8 function midfind(l,r,w: longint ):longint;
9 var
10 mid : longint;
11 begin
12 while l<r do
13 begin
14 mid:=(l+r)shr 1;
15 if a[mid]>=w then r:=mid
16 else l:=mid+1;
17 end;
18 exit(l);
19 end;
20 begin
21 a[1]:=2; n:=1000000;
22 for i:=2 to n do
23 if not v[i] then
24 begin
25 j:=1; inc(tot); a[tot]:=i;
26 while i*j<=n do
27 begin
28 v[i*j]:=true;
29 inc(j);
30 end;
31 end;
32 readln(x,y);
33 k:=midfind(1,tot+1,x);
34 if k=tot+1 then
35 begin
36 writeln(-1);
37 halt;
38 end;
39 while a[k+1]<=y do
40 begin
41 if a[k]+2=a[k+1] then
42 begin
43 bj:=true;
44 writeln(a[k],' ',a[k+1]);
45 end;
46 inc(k);
47 end;
48 if not bj then writeln(-1);
49 end.

二分是一个细节很多的function,需要多加练习,
必须达到怎么打都不错,看完就能打的地步。

posted @ 2012-04-08 07:57  SunSky...  阅读(282)  评论(0编辑  收藏  举报