/*
ID: 1590291
TASK: ariprog
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string.h>
/******************************************************************************************************************
简直了,纯暴力!!!
一道吐血的暴力题!!!
好多坑啊,注释写清楚了,仔细回味回味就知道了。
思路:
1,巧用 f 数组来优化复杂度。
2,通过内外循环来求得公差 d,接着遍历看看是否存在 N 个数满足此首项公差公式
3,找到公差公式后,将 (首项a和公差b) 保存在 Node ans[70000]答案数组里.
******************************************************************************************************************/
using namespace std;
struct Node
{
int a;
int b;
};
int f[700000],a[700000]; //为什么定义这么大就够了呢,因为有重复的。eg:66*66+77*77 = 77*77+66*66 标志数组
Node ans[700000];
bool cmp(Node x,Node y)
{
return x.b<y.b;
}
int main()
{
ifstream fin("ariprog.in");
ofstream fout("ariprog.out");
int N,M;
while(fin>>N>>M)
{
memset(f,0,sizeof(f));
int length=0,length1=0,flag;
for(int i = 0;i <= M;i ++){
for(int j = 0;j <= M;j ++){
f[i*i+j*j]=1; //巧用数组标志 true 和 false,简化了许多算法
}
}
for(int i = 0;i <= 2*M*M;i ++){
if(f[i]){
a[length]=i;
length++;
}
}
for(int i = 0;i < length;i ++){
for(int j = i+1;j < length;j ++){
int d=a[j]-a[i];
flag=1;
if(a[i] + (N-1)*d > 2*M*M) break; //越界了
for(int k = 2;k < N;k ++){ //上边界越界了。长度为 N 的等差数列,最后一个数是 a+(n-1)*d!!!
if(f[a[i]+k*d] == 0) //不属于双平方和数集合
flag=0;
}
if(flag){ //找到了长度为 N 的等差数列,保存在 Node 答案结构体里面
ans[length1].a=a[i];
ans[length1].b=d;
length1++;
}
}
}
sort(ans,ans+length1,cmp);
if(length1 == 0)
fout<<"NONE"<<endl;
else{
for(int i = 0;i < length1;i ++)
fout<<ans[i].a<<" "<<ans[i].b<<endl;
}
}
return 0;
}
USACO 1.4-Arithmetic Progressions
最新推荐文章于 2022-09-28 21:18:48 发布