思路来自此处点击打开链接
这道题目的题意很搞人啊,arithmetic progression是等差数列。就算不知道意思,应该也是能推断出来的(反正我是看了题解才知道)。输入两个数m,n。n代表数列的长度,m代表(0 <= p, q <= m)求出n数列长度的等差数列,其中元素x必须满足 x = p ^2 + q^2。
输出首项和公差。输出顺序是从小到大,公差为第一优先级,首项为第二优先级。
这一题暴力很容易想到,可是需要优化。首项,我们可以在给定m能求出的p^2 + q^2范围里查找。公差,一定不会大于最后一项减去首项除以(n - 1)
/**
ID: DickensTone
PROB: ariprog
LANG: C++
**/
#include<cstdio>
#include<cstring>
#include<fstream>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = (62500 + 5) * 2;
bool vis[maxn];
bool is_right(int s, int p, int len)
{
while(len--)
{
if(!vis[s]) return false;
s = s + p;
}
return true;
}
int num[maxn];
int cnt, n, m;
void init()
{
cnt = 0;
for(int i = 0; i <= m; i++)
for(int j = 0; j <= i; j++)
{
int t = i * i + j * j;
if(!vis[t])
{
vis[t] = 1;
num[cnt++] = t;
}
}
}
int main()
{
freopen("ariprog.in", "r", stdin);
freopen("ariprog.out", "w", stdout);
while(scanf("%d%d", &n, &m) == 2)
{
memset(num, 0, sizeof(num));
memset(vis, 0, sizeof(vis));
init();
sort(num, num + cnt);
bool flag = false;
int big_b = (num[cnt - 1] - num[0]) / (n - 1);
for(int i = 1; i <= big_b; i++)
for(int j = 0; num[j] + i * (n - 1) <= num[cnt - 1]; j++)
{
if(is_right(num[j], i, n))
{
flag = 1;
printf("%d %d\n", num[j], i);
}
}
if(flag == false)
printf("NONE\n");
}
return 0;
}