[USACO1.4]等差数列 Arithmetic Progressions

题目

题目描述

一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列。

在这个问题中a是一个非负的整数,b是正整数。写一个程序来找出在双平方数集合(双平方数集合是所有能表示成p的平方 + q的平方的数的集合,其中p和q为非负整数)S中长度为n的等差数列。

输入输出格式

输入格式:

 

第一行: N(3<= N<=25),要找的等差数列的长度。

第二行: M(1<= M<=250),搜索双平方数的上界0 <= p,q <= M。

 

输出格式:

 

如果没有找到数列,输出`NONE'。

如果找到了,输出一行或多行, 每行由二个整数组成:a,b。

这些行应该先按b排序再按a排序。

所求的等差数列将不会多于10,000个。

 

输入输出样例

输入样例#1: 
5
7
输出样例#1: 
1 4
37 4
2 8
29 8
1 12
5 12
13 12
17 12
5 20
2 24

题目大意

  题目刚开始我也看不懂

   后来懂了。。。

   其实就是在一个数列里找到长度为n的等差数列

   这个数列是(0到m)平方加上 (0到m)平方形成的所有的数

   输出第一个数的数值和公差即可

分析

    首先,当然是构建数列啦

   然后我们就要找等差数列啦

   等差数列从何入手呢?

   等差数列顾名思义是有一个公差的

   我们只需要枚举公差就好了

   于是我们通过枚举前两的在等差数列的数得到公差后

   向后查找其他数

   最后如果所有数存在就可以算一种了

   排序 就可以输出啦

    

   还有一个要注意的:

   一个很重要的优化点

   当数很多,公差很大时

   显然超时

   所以我们在查找前要加判断

   当  第一个数+(n-2)*公差>最大值时 break

   因为是有序的,当出现第一个大于最大值时,后面都不行

   

代码

 

  

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 int a[62500000],b[62500000];
 5 struct sb
 6 {
 7     int shu,cha;
 8 }ans[600000];
 9 bool cmp(sb a,sb b)
10 {
11     if (a.cha<b.cha) return true;
12     if (a.cha==b.cha)
13       if (a.shu<b.shu) return true;
14     return false;
15 }
16 int main ()
17 {
18     int n,m;
19     cin>>n>>m;
20     int k=1;
21     for (int i=0;i<=m;i++)  // 得到数列 
22        for (int j=i;j<=m;j++)
23        {
24             a[i*i+j*j]=1;
25             b[k++]=i*i+j*j;
26        }
27     sort(b+1,b+1+k);  //排序 
28     int wz=unique(b+1,b+1+k)-b; //因为会有重复,所以去重 
29     k=1;
30     for (int i=1;i<=wz;i++)
31     {
32         for (int j=i+1;j<=wz;j++)
33         {
34             int ca=b[j]-b[i],bj=0;
35             if (ca<=0) continue;   
36             if (b[j]+(n-2)*ca>2*m*m) break;  //优化 
37             for (int ii=1;ii<=n-2;ii++)
38             {
39                 if (a[b[j]+ii*ca]!=1)
40                 {
41                     bj=1;
42                     break;
43                 }
44             }
45             if (bj==0) {
46                 ans[k].shu=b[i];
47                 ans[k].cha=ca;
48                 k++;
49             }
50         }
51     }
52     sort(ans+1,ans+1+k,cmp);  //排序输出 
53     if (k<2) cout<<"NONE";
54     for (int i=2;i<=k;i++)
55       cout<<ans[i].shu<<" "<<ans[i].cha<<endl;
56 }

 

posted @ 2018-12-07 21:50  Melted_czj  阅读(210)  评论(0编辑  收藏  举报
body { background-color:whitesmoke; } // 修改背景颜色为半透明 #home,#sideBarMain>div,#blog-sidecolumn>div>div,.catListView{ background-color:rgba(255,255,255,0); } // 修改其他边框的颜色