原文翻譯:
翻譯者: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了