嗯到了第四個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; }