原题目:
题目大意:某些边长为整数的直角三角形四个可以拼成中间空出来一个正方形洞的大正方形,而在这些特殊的三角形当中,又有更特殊的可以让这个小正方形拼成整个大正方形,问这种更特殊的直角三角形,在周长小于1亿的情况下有多少个
解题思路:
for (i = 1; i <= N; i++) {
for (j = 1; j <= i; j++) {
p = i * i + j * j;
z = sqrt(p);
if (i + j + z > N)break;
if (sqrt(p) == (ll)sqrt(p)) {
if (z % (i - j) == 0&&i+j+z<N)ans1++;
}
}
}
时间复杂度约为O(N^2) ,显然无法完成原题目1e8的数据规模.
考虑优化算法:
void solve() {
ll i, j,k,x,y,z,p,q,u,v;
ll N = 100000000,NN=50000000;
M.NT.get_Ptg_r(N);
for (i = 1; i <= M.NT.Ptg_r_cnt; i++) {
if (M.NT.Ptg_r[i].c % (M.NT.Ptg_r[i].b - M.NT.Ptg_r[i].a) == 0) {
p = M.NT.Ptg_r[i].a + M.NT.Ptg_r[i].b + M.NT.Ptg_r[i].c;
for (j = 1; j * p < N; j++) {
ans1++;
}
}
}
printf("%lld\n", ans1);
}
对于原问题可以快速解决,但是当数据规模扩大到1e10时,需要花费的时间便达到了1分钟以上
更进一步:
算法效率得到了明显的提升,对于数据规模在1e10的情况下仍然可以相对快速解决
但是当数据规模进一步增长,则略显乏力。
再进一步:
void solve() {
ll i, j,k,x,y,z,p,q,u,v;
ll N = 100000000000000000,NN=50000000;
ans1 = 0;
ll X_1 =1, Y_1 = 1;
ll n, m;
ans2 = 0;
while (X_1+Y_1<N) {
u = 3 * X_1 + 4 * Y_1;
v = 2 * X_1 + 3 * Y_1;
m = v;
n = u + v;
X_1 = u;
Y_1 = v;
ans2 += N / (X_1 + Y_1);
}
printf("%lld\n",ans2);
}
此时该算法已经变得非常强大