原文翻译:

翻译者:timgreen

转载自:OIBH

一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)
在这个问题中a是一个非负的整数,b是正整数。
写一个程序来找出在双平方数集合S中长度为n的等差数列。
双平方数集合是所有能表示成p2+q2的数的集合。

PROGRAM NAME: ariprog

INPUT FORMAT

第一行:  N(3<= N<=25),要找的等差数列的长度。 
第二行:  M(1<= M<=250),搜索双平方数的上界0 <= p,q <= M。

SAMPLE INPUT (file ariprog.in)
5
7

OUTPUT FORMAT
如果没有找到数列,输出`NONE'。
如果找到了,输出一行或多行, 每行由于二个整数组成:a,b
这些行应该先按b排序再按a排序。
将不会有只多于10,000个等差数列。

SAMPLE OUTPUT (file ariprog.out)
1 4
37 4
2 8
29 8
1 12
5 12
13 12
17 12
5 20
2 24
这题的思路应该说还是比较容易想的,不过要已开始就想到不TLE的就有点难了,可以把形 如p^2+q^2的数都存起来,后来就可以直接去数组里面取了。
接下来就是找适合的a和b了。
我一开始的代码是最原始的,就是一个一个找,
for(int i = 0;i < index1-n+1;i++)
     {
      a = num[i];
      for(int j = i+1;j < index1;j++)
        {
         b = num[j]-a;
         now = a+b;
         count = 2;
         if(a + b*(n-1) > max_num)//这里是表示不可能找到满足条件的a和b
           continue;
        for(int k = j+1;k < index1;k++)
           {
            if(now+b == num[k])
              {
                now = num[k];
                count++;
                if(n == count)//如果找到,就退出
                   {
                    node[index2].a = a;
                    node[index2++].b = b;
                    break;
                   }
              }
              if(num[k] > now + b)//表示不可能找到合适的a和b
                 break;
           }        
     }

可是这样TLE,死在第7组数据上,听说第8组更强悍的数据。
后来搜了份报告,发现挺不错的,
代码如下
for(int i = 0;i < index1-n+1;i++)
     {
      a = num[i];
      for(int j = i+1;j < index1;j++)
        {
         b = num[j]-a;
         now = a+b;
         count = 2;
         if(a + b*(n-1) > max_num)
           continue;
         can = true;
         for(int k = 2;k < n;k++)
           {
            if(!isexict[a+b*k])//isexict[i]表示i可以表示成p^2+q^2不
             {
              can = false;
              break;
             }
           }
         if(can)
          {
           node[index2].a = a;
           node[index2++].b = b;
           }
        }
     }
我的思路是一直找,找合适的,但是上面这个就是找不合适的,这样肯定会快,因为这里面不合适的多得多。这就是枚举时不同的方法,差别很大啊
不过还有人能在第8组数据上之用0.63S,可是我的用了1.46S,看来还有更好的,继续学习。
不过现在我再改了下,第8组数据也只要0.43S了,也就是把下第二个程序的
         if(a + b*(n-1) > max_num)
           continue;
  中的continue;改成break;因为当这个不可能的时候,下面的b只会比这个还大,那肯定不行,所以就直接break了