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;
}