美国队长3 3d蓝光原盘:pascal题 急!!

来源:百度文库 编辑:神马品牌网 时间:2024/05/03 05:52:46
全国青少年信息学(计算机)奥林匹克分区联赛普及组 复赛第一道
问题A : 亲和数 ( Amicable Number )
问题描述:
某一天,tenshi看了一本趣味数学书,上面提到了亲和数:定义数对 (x,y) 为亲和数对当且仅仅当x、y为不同正整数,且x、y各自的所有非自身正因子之和等于另一个数。例如 (220,284) 和 (280,224) 都是亲和数对,因为:
220的所有非自身正因子之和为:1 + 2 + 4 + 5 + 10 + 11 + 20 + 22 + 44 + 55 + 110 = 284
284的所有非自身正因子之和为:1 + 2 + 4 + 71 + 142 = 220
数对 (x,y ) 跟 (y,x) 被认为是同一数对,所以我们只考虑 x<y 的情况。
任 务 :tenshi对某个范围内的亲和数对的数量非常感兴趣,所以希望你能帮她编写一个程序计算给定范围内的亲和数对的数量。给定一个范围A到B,如果A≤ x ≤ B,则我们称 (x,y)在范围[A,B]内。

输入格式:
从文件的第一行分别读入正整数A和B,其中A、B满足
1 ≤ A ≤ B ≤ 108 且 B-A ≤ 105
输出格式:
输出文件只有一行,就是[A,B]内亲和数对的数量

样例:
AMICABLE.INP AMICABLE.OUT
200 1200
2

注:[200,1200] 内的数对只有两个,分别是(220,284)和(1184 1210)
求整个程序,正确还有加分!!

风元素改一下程序吧,感觉你的答案复杂度高了点,都O(n^3)了,如果稍微想一下就可以降到O(n^(3/2))
手头没有pascal的编译器,写了个java的
//find(a,b)返回a到b之间的数对个数
int find(int a,int b){
int[] store = new int[b - a];
//初始化store使得store[i-a]=i所有因数之和
for (int i = a; i < b; i++) {
int s = 1;
for (int j = 2; j * j <= i && s < b; j++) {
if (i % j == 0) {
s += j;
if (j * j != i) {
s += i / j;
}
}
}
store[i - a] = s;
}
//查找
int count = 0;
for (int i = a; i < b; i++) {
int f = store[i - a];
if (f != 0 && store[f - a] == i && f != i) {
count++;
}
}
return count / 2;
}

Var
i,j,k1,k2,a,b:word;t,f:text;s,p:longint;
Begin
assing(f,'amicable.in');reset(f);
readln(f,a,b);
close(f);
p:=0;
For i:=a To b-1 Do
For j:=i To b Do
Begin
s:=0;
For k:=1 To i-1 Do If (i Mod k)=0 Then inc(s,k);
For k:=1 To j-1 Do If (j Mod k)=0 Then dec(s,k);
If s=0 Then inc(p)
End;
assign(t,'amicable.out');rewrite(t);
writeln(t,p);
close(t)
End.

自己去买本Pascal的书吧,这种问题打得手累而且一看就懂