usaco1.4.3( ariprog )

题目:

Arithmetic Progressions

An arithmetic progression is a sequence of the form a, a+b, a+2b, ..., a+nb where n=0,1,2,3,... . For this problem, a is a non-negative integer and b is a positive integer.

Write a program that finds all arithmetic progressions of length n in the set S of bisquares. The set of bisquares is defined as the set of all integers of the form p2 + q2 (where p and q are non-negative integers).

TIME LIMIT: 5 secs

PROGRAM NAME: ariprog

INPUT FORMAT

Line 1: N (3 <= N <= 25), the length of progressions for which to search
Line 2: M (1 <= M <= 250), an upper bound to limit the search to the bisquares with 0 <= p,q <= M.

SAMPLE INPUT (file ariprog.in)

5
7

OUTPUT FORMAT

If no sequence is found, a singe line reading `NONE'. Otherwise, output one or more lines, each with two integers: the first element in a found sequence and the difference between consecutive elements in the same sequence. The lines should be ordered with smallest-difference sequences first and smallest starting number within those sequences first.

There will be no more than 10,000 sequences.

SAMPLE OUTPUT (file ariprog.out)

1 4
37 4
2 8
29 8
1 12
5 12
13 12
17 12
5 20
2 24

前两题题目没看懂,先跳着看,感觉这个题目应该能出来。先试试。
题意还是蛮好懂,找到一个长度为N的等差数列,是数列的每一项都是双平方数。枚举首项和公差,结果在第6组数据上超时了,先把超时代码贴上来,再想想能不能优化。

 终于找到优化了,枚举首相和公差时,有个条件就是最后一项必须小于2*m*m,当前公差不行的话,后面的都不行(都大了),直接break;

代码就直接:

/*
ID:614433244
PROG: ariprog
LANG: C++
*/

#include"iostream"
#include"cstdio"
#include"algorithm"
#include"cmath"
using namespace std;
struct M
{
    int a,b;
}ans[10005];
int rr=0;
int n,m;
int a[250*250],t;

bool bsearch( int l,int r,int p )
{
    int temp=(l+r)/2;
    if( r-l==1 )
    {
        if( a[r]==p||a[l]==p )
            return true;
        if( a[r]!=p&&a[l]!=p )
            return false;
    }
    if( a[temp]==p )
        return true;
    if( l==r )
    {
        if( a[l]==p )
            return true;
        else
            return false;
    }
    if( a[temp]<p )
        return bsearch( temp,r,p );
    if( a[temp]>p )
        return bsearch( l,temp,p );
}
bool cmp( M a,M b )
{
    if( b.b==a.b )
        return a.a<b.a;
    else
        return a.b<b.b;
}
int main()
{
    freopen("ariprog.in","r",stdin);
    freopen("ariprog.out","w",stdout);
    scanf("%d%d",&n,&m);
    int i,j,k;
    for( i=0;i<=m;i++ )
        for( j=i;j<=m;j++ )
        {
            a[t]=i*i+j*j;
            t++;
        }
    sort( a,a+t );
    i=t;
    t=0;
    j=1;
    while( j<i )
    {
        if( a[j]==a[t] )
            j++;
        else
        {
            t++;
            a[t]=a[j];
            j++;
        }
    }
//for( i=0;i<=t;i++ )
//cout<<a[i]<<" ";cout<<endl;
    int p;
    for( i=0;i<=t-n+1;i++ )
    {
        for( j=i+1;j<=t-n+2;j++ )//确定前两项也就是确定了公差
        {
            k=n-2;
            p=a[j]-a[i];
            if( a[i]+(n-1)*p >2*m*m )
                break;
            int c=a[j];
            c=c+p;
            while( bsearch( j+1,t,c )&&k>=0 )
            {
                k--;c=c+p;
            }
            if( k<=0 )
            {
                ans[rr].a=a[i];
                ans[rr].b=p;
                rr++;
            }
        }
    }
    sort( ans,ans+rr,cmp );
    if( rr==0 )
        printf("NONE\n");
    else
        for( i=0;i<rr;i++ )
            printf("%d %d\n",ans[i].a,ans[i].b);
    return 0;
}

过个题真特么慢啊,还是这么简单的题。

 

 
posted @ 2012-07-08 10:37  萧若离  阅读(291)  评论(0)    收藏  举报