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
问题描述:
查找特定序列(平方和序列)的指定长度等比子序列。唯一限定条件是:时间不能超过5s。但是空间模式JVM的最大堆内存配置,应当在32M-64M左右(个人估计)。
思路:
应当算是一个BFS搜索,对每个等比间隔i,遍历bisquare_sequence每一项看其是否为某个长度为N间隔为i的等比序列的首项(自然该等比序列的其他元素亦在bisquare_sequenc中)。
时间复杂度:O(i*k*n):i为间隔的可能值((2 * P*P + 1) / (N - 1));k为bisquare_sequence序列(P*P);n为子序列长度。
空间复杂度:O(2 * P*P + 1).申请了一个一维数组来保存bisquare_sequence信息。
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; public class ariprog { public static void main(String[] args) throws IOException, FileNotFoundException { BufferedReader br = new BufferedReader(new FileReader("ariprog.in")); FileWriter fout = new FileWriter("ariprog.out"); boolean trigger = false; int N = Integer.parseInt(br.readLine()); int P = Integer.parseInt(br.readLine()); int P_2 = P * P; int interval_limit = (2 * P_2 + 1) / (N - 1); int[] bisquares = new int[2 * P_2 + 1]; ArrayList<Integer> list = pre_process(bisquares, P); long start = System.currentTimeMillis(); for (int i = 1; i < interval_limit+1; i++) { int limit = (2 * P_2 + 1 - (N - 1) * i); for (int k = 0; k < list.size() && list.get(k) < limit; k++) { if (check(i, list.get(k), bisquares, N)) { fout.write(list.get(k) + " " + i + "\n"); trigger = true; } } } if (!trigger) fout.write("NONE\n"); long end = System.currentTimeMillis(); System.out.println(end - start); fout.flush(); fout.close(); br.close(); System.exit(0); } private static ArrayList<Integer> pre_process(int[] bisquares, int P) { ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < P + 1; i++) { for (int j = 0; j < P + 1; j++) { if (bisquares[i * i + j * j] != 1) { list.add(i * i + j * j); bisquares[i * i + j * j] = 1; } } } Collections.sort(list); return list; } private static boolean check(int i, int k, int[] bisquares, int length) { for (int j = k; j < length * i + k;) { if (bisquares[j] != 1) return false; j += i; } return true; } }