Description
输入正整数k(k<=1000),将1/k变为不少于2项,但不多于3项的1/(xi)之和,xi为正整数,且i表示序号
注:请使用long long
输入格式
多case,一行一个整数k
最后一行是0
输出格式
对每一个case,按等式最右边一项分母,由小到大排序输出满足条件的等式,最右边一项分母相同,则按最右边第二项,依次类推
每一个case完成后,输出一个空行(没有满足的等式时,也要输出该空行)
输入样例
2
3
4
0
输出样例
1/2=1/6+1/3
1/2=1/42+1/7+1/3
1/2=1/24+1/8+1/3
1/2=1/18+1/9+1/3
1/2=1/15+1/10+1/3
1/2=1/12+1/12+1/3
1/2=1/4+1/4
1/2=1/20+1/5+1/4
1/2=1/12+1/6+1/4
1/2=1/8+1/8+1/4
1/2=1/10+1/5+1/5
1/2=1/6+1/6+1/6
1/3=1/12+1/4
1/3=1/156+1/13+1/4
1/3=1/84+1/14+1/4
1/3=1/60+1/15+1/4
1/3=1/48+1/16+1/4
1/3=1/36+1/18+1/4
1/3=1/30+1/20+1/4
1/3=1/28+1/21+1/4
1/3=1/24+1/24+1/4
1/3=1/120+1/8+1/5
1/3=1/45+1/9+1/5
1/3=1/30+1/10+1/5
1/3=1/20+1/12+1/5
1/3=1/15+1/15+1/5
1/3=1/6+1/6
1/3=1/42+1/7+1/6
1/3=1/24+1/8+1/6
1/3=1/18+1/9+1/6
1/3=1/15+1/10+1/6
1/3=1/12+1/12+1/6
1/3=1/21+1/7+1/7
1/3=1/12+1/8+1/8
1/3=1/9+1/9+1/9
1/4=1/20+1/5
1/4=1/420+1/21+1/5
1/4=1/220+1/22+1/5
1/4=1/120+1/24+1/5
1/4=1/100+1/25+1/5
1/4=1/70+1/28+1/5
1/4=1/60+1/30+1/5
1/4=1/45+1/36+1/5
1/4=1/40+1/40+1/5
1/4=1/12+1/6
1/4=1/156+1/13+1/6
1/4=1/84+1/14+1/6
1/4=1/60+1/15+1/6
1/4=1/48+1/16+1/6
1/4=1/36+1/18+1/6
1/4=1/30+1/20+1/6
1/4=1/28+1/21+1/6
1/4=1/24+1/24+1/6
1/4=1/140+1/10+1/7
1/4=1/42+1/12+1/7
1/4=1/28+1/14+1/7
1/4=1/8+1/8
1/4=1/72+1/9+1/8
1/4=1/40+1/10+1/8
1/4=1/24+1/12+1/8
1/4=1/16+1/16+1/8
1/4=1/36+1/9+1/9
1/4=1/18+1/12+1/9
1/4=1/20+1/10+1/10
1/4=1/15+1/12+1/10
1/4=1/12+1/12+1/12
思路:
①、了解式子的格式为:1/k = 1/x + 1/y + 1/z,并且x >= y >= z > k
②、求z范围:因为x>=y>=z>k 所以1/x<=1/y<=1/z 又因为1/k = 1/x + 1/y + 1/z <= 3/z 所以 1/k <= 3/z 则z<=3*k
③、先判断两项的输出,即1/k = 1/y + 1/z
④、已知k,z,若拆分成两项成立,则根据关系,所求y一定为整数,1/y=1/k-1/z, 即 y=k*z/(z-k)
⑤、判断y是否为整数并且式子符合大小关系,如果符合,则输出
⑥、判断三项是否成立,即1/k=1/x+1/y+1/z
⑦、此时固定z,已知1/x+1/y的和为1/k-1/z,思路跟上面类似,将1/k-1/z的结果作为一项进行拆分,注意这个结果可能无法划分为1/某数的形式
⑧、求此时的较小数y的范围,此时y的范围为:k*z/(z-k)+1 ~ 2*(k*z/(z-k))+1
⑨、已知k、y、z,若式子成立,则所求x一定为整数,因为1/x=1/k-1/y-1/z 所以x=k*y*z/(y*z-k*z-k*y)
⑩、判断x是否为整数并且式子符合大小关系,如果符合,则输出
代码:
#include <cstdio>
#include<iostream>
using namespace std;
int main()
{
long long x, y, z, k;
while (cin>>k && k)
{
//式子的格式为1/k = 1/x + 1/y + 1/z
/*
因为x>=y>=z>k 所以1/x<=1/y<=1/z 又因为1/k = 1/x + 1/y + 1/z <= 3/z 所以 1/k <= 3/z 则z<=3*k
*/
for (z = k+1; z <= 3*k; z++)
{
//先判断两项是否成立,即1/k==1/y+1/z
//已知k,z,若成立,则所求中y一定为整数,1/y==1/k-1/z, 即 y=k*z/(z-k)
y=k*z/(z-k);
if((k*z)%(z-k) == 0 && y>=z)//随着z的递增,y有可能小于z,则判断如果y大于z,则输出式子1/k==1/y+1/z
printf("1/%lld=1/%lld+1/%lld\n",k,y,z);
//判断三项是否成立,即1/k=1/x+1/y+1/z
//已知1/x+1/y的和为1/k-1/z,思路跟上面类似,将1/k-1/z作为一项进行拆分,这个结果可能无法划分为1/某数的形式
int p = k*z/(z-k);
for(y=p+1; y <= 2*p+1; y++)
{
//因为1/x=1/k-1/y-1/z 所以x=k*y*z/(y*z-k*z-k*y)
//若式子成立,则x一定为整数
x=k*y*z/(y*z-k*z-k*y);
if ((k*y*z) % (y*z-k*z-k*y) == 0 && x>=y && y>=z)//如果x>=y>=z,则输出
printf("1/%lld=1/%lld+1/%lld+1/%lld\n",k,x,y,z);
}
}
printf("\n");
}
return 0;
}