USACO1.4.3 Arithmetic Progressions 等差數列 解題報告(列舉)
阿新 • • 發佈:2018-12-09
Description
一個等差數列是一個能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的數列。 在這個問題中a是一個非負的整數,b是正整數。寫一個程式來找出在雙平方數集合(雙平方數集合是所有能表示成p^2+q^2的數的集合)S中長度為n的等差數列。
Input
第一行: N(3<= N<=25),要找的等差數列的長度。 第二行: M(1<= M<=250),搜尋雙平方數的上界0 <= p,q <= M。
Output
如果沒有找到數列,輸出`NONE'。 如果找到了,輸出一行或多行, 每行由二個整陣列成:a,b。 這些行應該先按b排序再按a排序。 所求的等差數列將不會多於10,000個。
Sample Input
5 7
Sample Output
1 4 37 4 2 8 29 8 1 12 5 12 13 12 17 12 5 20 2 24
這裡需要注意M<=250,所以所有的種類數只有250^2 = 62500,對於長度至多為25的資料完全可以暴力解決
#include <map> #include <cmath> #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> #define lowbit(a) (a&(-a)) #define _mid(a,b) ((a+b)/2) #define _mem(a,b) memset(a,0,(b+3)<<2) #define fori(a) for(int i=0;i<a;i++) #define forj(a) for(int j=0;j<a;j++) #define ifor(a) for(int i=1;i<=a;i++) #define jfor(a) for(int j=1;j<=a;j++) #define mem(a,b) memset(a,b,sizeof(a)) #define IN freopen("in.txt","r",stdin) #define OUT freopen("out.txt","w",stdout) #define IO do{\ ios::sync_with_stdio(false);\ cin.tie(0);\ cout.tie(0);}while(0) using namespace std; typedef long long ll; const int maxn = 5*1e6+10; const int INF = 0x3f3f3f3f; const int inf = 0x3f; const double EPS = 1e-7; const double Pi = acos(-1); const int MOD = 1e9+7; bool a[maxn]; bool use[maxn]; int num[maxn]; int main() { //IN; int k = 0; int Max = -INF; int n,m; cin >> n >> m; fori(m+1) //存下所有q*q+p*p的組合 forj(i+1) { if(!a[i*i+j*j]) { num[k++] = i*i+j*j; a[i*i+j*j] = true; Max = max(Max,num[k-1]); } } sort(num,num+k); int d; bool res = false; for(int j=1; j*(n-1)<=Max; j++) { //暴力求解即可 for(int i=0; i<k; i++) { int step = 1; d = num[i]; while(a[d+j]&&step<n) { d += j; step ++; } if(step>=n){ res = true; cout << num[i] <<" "<< j << endl; } } } if(!res) cout <<"NONE"<<endl; return 0; }