zoukankan      html  css  js  c++  java
  • [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 }
    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    Orleans is a framework
    修改emlog后台登录路径的方法(转)
    form表单中的 action=./?> 是什么意思
    10 个迅速提升你 Git 水平的提示(转)
    为什么国外程序员爱用苹果Mac电脑?(转)
    Socket 专题
    Android 时间戳简单转化
    Android 常用时间格式转换代码
    Android AlarmManager(全局定时器/闹钟)指定时长或以周期形式执行某项操作
    Android AlarmManager类的应用(实现闹钟功能)
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/10085450.html
Copyright © 2011-2022 走看看