zoukankan      html  css  js  c++  java
  • USACO Section1.4 Arithmetic Progressions 解题报告

        ariprog解题报告 —— icedream61 博客园(转载请注明出处)
    ------------------------------------------------------------------------------------------------------------------------------------------------
    【题目】
      找出所有在双平方数集合S中长度为N的等差数列。
      双平方数集合S:所有能表示成p²+q²的数的集合,其中0<=p,q<=M。
    【数据范围】
      3<=N<=25
      1<=M<=250
    【输入格式】
      N
      M
    【输出格式】
      没找到数列,输出“NONE”。
      找到数列了,就输出所有数列,每个数列占一行,格式为“a b”,a为首项、b为公差。
      输出顺序:先按b升序,再按a升序。
    【输入样例】
      5
      7
    【输出样例】
      1 4
      37 4
      2 8
      29 8
      1 12
      5 12
      13 12
      17 12
      5 20
      2 24
    ------------------------------------------------------------------------------------------------------------------------------------------------
    【分析】
      先把S求出来。
      然后以其中任何一个数a为首项,任何一个比a大的数b为第二项,便可得到一个等差数列。再数到第N项,若此N项均在集合S中,则此数列合法。
      最后将所有数列按照题目要求排序,输出即可。
    ------------------------------------------------------------------------------------------------------------------------------------------------
    【总结】
      第一次提交,卡在了第7个点上,运行时错误。
        拿来数据一试,发现本机运行时间1.5s,看来算法需要改进。
        把我的ok函数中*改成+,时间变为1s,不大保险,继续改进。(不过继续改进暂时没思路,先交上去看看……)
        这次发现自己又粗心了!OJ上并未说我超时,我的代码只被运行了0.003s就停了,就是单纯的运行时错误!
        不过本机运行没报错……看了会儿代码找不到越界,先去吃饭~
        去吃饭路上想到哪儿错了~果然是有个地方数组下标越界,严谨性还是太差啊!
      第二次提交,AC。
        原来这题时间限制不是1s啊……2.2s也能过,我多虑了……

    ------------------------------------------------------------------------------------------------------------------------------------------------

    【代码】

     1 /*
     2 ID: icedrea1
     3 PROB: ariprog
     4 LANG: C++
     5 */
     6 
     7 #include <iostream>
     8 #include <fstream>
     9 using namespace std;
    10 
    11 const int maxd = 125000;
    12 
    13 int N,M;
    14 bool d[1+maxd];
    15 
    16 int L;
    17 int num[maxd]; // maxd只是随便写的
    18 
    19 int l;
    20 struct Result
    21 {
    22     int a,b;
    23     friend bool operator<(Result const &x,Result const &y) { return x.b<y.b || x.b==y.b && x.a<y.a; }
    24 }A[10001];
    25 
    26 bool ok(int a,int b)
    27 {
    28     //cout<<"a="<<a<<"	b="<<b<<endl;
    29     for(int i=1;i<N;++i)
    30     {
    31         a+=b;
    32         if(a>maxd || !d[a]) return false;
    33     }
    34     return true;
    35 }
    36 
    37 void qsort(int l,int r) // 注意,这里的l和全局的l并存,不会有错误~
    38 {
    39     if(l>=r) return;
    40     int i=l,j=r;
    41     Result x=A[(l+r)>>1];
    42     while(1)
    43     {
    44         while(A[i]<x) ++i;
    45         while(x<A[j]) --j;
    46         if(i>j) break;
    47         swap(A[i],A[j]);
    48         ++i; --j;
    49     }
    50     qsort(l,j); qsort(i,r);
    51 }
    52 
    53 int main()
    54 {
    55     ifstream in("ariprog.in");
    56     ofstream out("ariprog.out");
    57 
    58     in>>N>>M;
    59 
    60     for(int p=0;p<=M;++p)
    61         for(int q=p;q<=M;++q) d[p*p+q*q]=true;
    62 
    63     for(int i=0;i<=maxd;++i)
    64         if(d[i]) num[++L]=i;
    65 
    66     for(int i=1;i<=L;++i)
    67     {
    68         int a=num[i];
    69         for(int j=i+1;j<=L;++j)
    70         {
    71             int b=num[j]-a;
    72             if(ok(a,b))
    73             {
    74                 ++l; A[l].a=a; A[l].b=b;
    75                 //cout<<"A=("<<a<<","<<b<<")"<<endl; cin.get();
    76             }
    77         }
    78     }
    79 
    80     qsort(1,l);
    81 
    82     if(!l) out<<"NONE"<<endl;
    83     else for(int i=1;i<=l;++i) out<<A[i].a<<" "<<A[i].b<<endl;
    84 
    85     in.close();
    86     out.close();
    87     return 0;
    88 }
  • 相关阅读:
    四则运算出题系统,java
    Javaweb测试
    《构建之法》 读书笔记(6)
    使用ProcDump在程序没有响应时自动收集dump
    NASA关于如何写出安全代码的10条军规
    C#和C++中的float类型
    避免在C#中使用析构函数Finalizer
    C#性能优化的一些技巧
    从bug中学习怎么写代码
    Code Smell那么多,应该先改哪一个?
  • 原文地址:https://www.cnblogs.com/icedream61/p/4323296.html
Copyright © 2011-2022 走看看