Arithmetic Progressions

Problem:

Arithmetic Progressions

An arithmetic progression is a sequence of the form a, a+b, a+2b, ..., a+nb where n=0,1,2,3,... . For this problem, a is a non-negative integer and b is a positive integer.

Write a program that finds all arithmetic progressions of length n in the set S of bisquares. The set of bisquares is defined as the set of all integers of the form p2 + q2 (where p and q are non-negative integers).

TIME LIMIT: 5 secs

PROGRAM NAME: ariprog

INPUT FORMAT

Line 1: N (3 <= N <= 25), the length of progressions for which to search
Line 2: M (1 <= M <= 250), an upper bound to limit the search to the bisquares with 0 <= p,q <= M.

SAMPLE INPUT (file ariprog.in)

5
7

OUTPUT FORMAT

If no sequence is found, a singe line reading `NONE'. Otherwise, output one or more lines, each with two integers: the first element in a found sequence and the difference between consecutive elements in the same sequence. The lines should be ordered with smallest-difference sequences first and smallest starting number within those sequences first.

There will be no more than 10,000 sequences.

SAMPLE OUTPUT (file ariprog.out)

1 4
37 4
2 8
29 8
1 12
5 12
13 12
17 12
5 20
2 24

 


 


MY GAIN:
一开始的算法糟糕透了。
1.并不是生成好双平方数然后依次去检验。
  而是从0到max对a和b用两层循环去不断生成等差数列,然后一一去check是否为双平方数。算是穷举吧T T
  举个例子,当n=18,m=100,max=2*100*100,这种算法所需的时间近,18*20000*20000=7.2*10^9 >> 2000000(穷举法使用范围)。
2.也没有使用快排。
  而直接用了STL的优先级队列。一个struct类型数组保存a和b数对。先对b依次入了队,出队后再对相同b的a入队。

现在使用的这个算法是在别人的博客里学来的,基本思想如下:
1.对[0,m]范围之内的p,q生成所有双平方数,保存在Bisquare数组中,并建立了一个2*m*m+1大小的数组isBisquare来保存每个数是否为双平方数(便于检验ab)。
  这里应当注意的是,new出来的bool数组默认值是true,要一一手动赋值。
2.对Bisquare数组快速排序。这即是对a的排序。
  另外应注意到,Bisquare数组中其实是可能有重复元素的。经过快排,它们也移动到一起,便于后来skip之。
3.因为先对b排序,再对a排序,所以外层循环是b,内层是a。
  为了保证等差数列最大元素a+(n-1)*b<=max,必须有(n-1)*b<=max。是b的循环条件。
  而等差数列第一个元素即为a,故a根本不需从0到max-1依次++,只需要a依次是Bisquare中的元素即可。
  由于有相等元素,需要用一个last来进行比较,skip相等的元素值。last的初始化位置需要注意。
4.判断a和b是否满足条件,满足则输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值