嗯到了第四个section,好吧认真一点。这题NOCOW上有更快的解法,下面也会详细说,估计我这个方法是最慢的一种了。
题目概述:
找等差数列,给定等差数列的长度n,和另一个数q,等差数列要求每一个数都可以表示成 i^2+j^2 , 0<= i,j <= q 的形式。然后输出结果先按等差排序再按首项排序。
算法思想:
我自己的想法概括起来就只有两点,首先预处理一个b数组,记录了这个数能不能写成 i^2+j^2 的形式。
其次就是直接先暴力枚举等差,再暴力枚举首项。枚举到了当即输出就行,因为这个顺序要求就是题目的要求。
当然首项和等差是有范围的,用一点数学知识剪枝就好了。
代码部分:
#include <iostream> #include <list> #include <map> #include <math.h> #include <string.h> #include <string> #include <fstream> #include <algorithm> using namespace std; ifstream fin("ariprog.in"); ofstream fout("ariprog.out"); int n,up_bound; int b[135017]; int main() { fin >> n >> up_bound; for (int i = 0; i <= up_bound; i++) { for (int j = 0; j <= up_bound; j++) { b[i*i + j*j] = 1; } } bool super_flag = false; int ma = 2*up_bound*up_bound / (n-1); for (int d = 1; d <= ma; d++) { int ma_1 = 2*up_bound*up_bound - (n - 1)* d; if (ma_1 < 0) ma_1 = 0; for (int start = 0; start <= ma_1; start++) { bool flag = true; for (int i = 0; i < n; i++) { if (b[start+i*d] == 0) { flag = false; break; } } if (flag) { super_flag = true; fout << start << " " << d << endl; } } } if (!super_flag) fout << "NONE" << endl; return 0; }