[U]Arithmetic Progressions 枚举

简单的枚举题。

题意是在一个集合S中求等差数列,输出等差数列的首项与公差。集合S中的元素是两个非负数的平方和。题目给出等差数列的项数,集合元素的范围。

思路:用一个bool数组记录该位置的数是否属于集合S。如果直接枚举公差很容易超时。这里可以减枝,使用一个list数组将bool数组中有效的元素全部保存起来。这样取出首项与公比就更快速了。另外要优化的就是判断最后一项是否在集合S中。

/*
ID:seven4
LANG:C++
PROG:ariprog
*/
#include<stdio.h>
#include<algorithm>
using namespace std;

bool temp[250*250*2+1];
int list[250*250*2+1];

struct node
{
 	   int a,d;
}ans[10001];
 	
bool cmp( node a,node b )
{ 
  	 if(a.d==b.d) return a.a<b.a;
  	 else return a.d<b.d;
}

bool cmplist( int a,int b ){return a<b;}

int main()
{
 	freopen( "ariprog.in","r",stdin );
 	freopen( "ariprog.out","w",stdout );
 	int N,M;
	
	for( int i=0;i<=250*250*2;i++ )
 		 temp[i]=false;
    	 
 	scanf( "%d %d",&N,&M );
 	int top=M*M*2;
	
	for( int p=0;p<=M;p++ )
 		 for( int q=0;q<=M;q++ )
 		 	  temp[p*p+q*q]=true;
		 
	int k=0;
 	for( int i=0;i<=top;i++ )
 		 if( temp[i] ) list[k++]=i;
 	sort( list,list+k,cmplist );
	 //枚举首项a和等差d
 	int t=0;
 	for( int i=0;i<k;i++ )
 	{
	 	 for( int j=i+1;j<k;j++ ) 
 		 {
		  	  if( list[j]==list[i] )
	 	 	  	  continue;
  	  		  int d=list[j]-list[i];
  	  		  
	 	  	  if( (list[i]+(N-1)*d)>top )
	 	 	  	  continue;
	 	 	  bool flag=true;
	 	 	  for( int s=1;s<N;s++ )
	 	 	  {
			   	   if( temp[list[i]+s*d]==false ){
			   	   	   flag=false;break;
				   }
   	   		  }
   	   		  if( flag ){
			   	  ans[t].a=list[i];
			   	  ans[t].d=d;
			   	  t++;
   	  	   	  }
		 }
	}
	if( t==0 )
		printf( "NONE\n" );
	else
	{
	 	sort( ans,ans+t,cmp );
		for( int i=0;i<t;i++ )
	 		 printf( "%d %d\n",ans[i].a,ans[i].d );
    }
 	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值