usaco1.4.3( ariprog )
题目:
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; }
过个题真特么慢啊,还是这么简单的题。
浙公网安备 33010602011771号