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