题目大意:
题目链接:https://jzoj.net/senior/#main/show/5773
题目图片:
https://www.z4a.net/images/2018/09/22/Screenshot.md.png
https://www.z4a.net/images/2018/09/22/Screenshot-1.png
给出
N
N
N,求
N
−
1
2
T
N
−
T
\frac{N-\frac{1}{2}T}{N-T}
N−TN−21T值为正整数时
T
T
T的所有正整数解(
0
<
T
<
N
0<T<N
0<T<N)。
思路:
40分做法:
N
≤
1
0
6
N\leq 10^6
N≤106
直接暴力枚举
T
T
T,输出符合要求的即可。
100分做法:
首先,我们要求的是
N
−
1
2
T
N
−
T
\frac{N-\frac{1}{2}T}{N-T}
N−TN−21T
设
x
=
N
−
T
x=N-T
x=N−T,那么就有
N
−
1
2
T
x
\frac{N-\frac{1}{2}T}{x}
xN−21T
我们知道,
T
=
N
−
N
+
T
=
N
−
(
N
−
T
)
T=N-N+T=N-(N-T)
T=N−N+T=N−(N−T),所以
N
−
1
2
[
N
−
(
N
−
T
)
]
x
\frac{N-\frac{1}{2}[N-(N-T)]}{x}
xN−21[N−(N−T)]
用乘法分配律脱括号
N
−
1
2
N
+
1
2
(
N
−
T
)
x
\frac{N-\frac{1}{2}N+\frac{1}{2}(N-T)}{x}
xN−21N+21(N−T)
拆成两半
N
−
1
2
N
x
+
1
2
(
N
−
T
)
x
\frac{N-\frac{1}{2}N}{x}+\frac{\frac {1}{2}(N-T)}{x}
xN−21N+x21(N−T)
左边可以简化
1
2
N
x
+
1
2
(
N
−
T
)
x
\frac{\frac{1}{2}N}{x}+\frac{\frac {1}{2}(N-T)}{x}
x21N+x21(N−T)
一开始设了
x
=
N
−
T
x=N-T
x=N−T,右边有一项就是
N
−
T
N-T
N−T,所以我们可以把它简化成
1
2
N
x
+
1
2
x
x
\frac{\frac{1}{2}N}{x}+\frac{\frac {1}{2}x}{x}
x21N+x21x
右边约分得
1
2
N
x
+
1
2
\frac{\frac{1}{2}N}{x}+\frac {1}{2}
x21N+21
我们知道,这个式子的值必须是个整数。我们设答案为整数
k
k
k
1
2
N
x
+
1
2
=
k
\frac{\frac{1}{2}N}{x}+\frac {1}{2}=k
x21N+21=k
等号两边同时乘2得
N
x
+
1
=
2
k
\frac{N}{x}+1=2k
xN+1=2k
那么由于
2
k
2k
2k和1都是整数,所以就有
N
x
\frac{N}{x}
xN也是整数
当
N
x
\frac{N}{x}
xN为整数时,
x
x
x就一定是
N
N
N的因数,所以
N
−
T
N-T
N−T就一定是
N
N
N的因数!
那么我们就枚举
N
N
N的因数
d
[
i
]
d[i]
d[i],当
d
[
i
]
+
1
2
\frac{d[i]+1}{2}
2d[i]+1为正整数(即
d
[
i
]
d[i]
d[i]是奇数)时,
N
−
d
[
i
]
N-d[i]
N−d[i]就是一个合法的解!
代码:
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#define N 2000100
#define ll long long
using namespace std;
ll n,a[N],d[N],sum,ans;
int main()
{
cin>>n;
for (ll i=1;i<=sqrt(n);i++) //求出n的所有因数
if ((n%i)==0)
{
if (i*i==n) d[++sum]=i;
else
{
d[++sum]=i;
d[++sum]=n/i;
}
}
for (ll i=1;i<=sum;i++)
{
if (((n/d[i])%2)&&n-d[i]) //符合要求
a[++ans]=n-d[i];
}
sort(a+1,a+1+ans);
cout<<ans;
for (int i=1;i<=ans;i++)
cout<<' '<<a[i];
return 0;
}