USACO 1.4-Arithmetic Progressions

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


posted on 2016-04-06 00:06  Jstyle  阅读(107)  评论(0编辑  收藏  举报

导航