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<<"\tb="<<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 }

 

posted on 2015-03-09 12:50  IceDream61  阅读(348)  评论(0编辑  收藏  举报

导航