10_19 毕达哥拉斯三元组和查找数列


前言

今天分享两道OJ题目,因为解题思路都很简单,重点是要学会算法的优化,以更少的循环次数解决问题。

毕达哥拉斯三元组

在这里插入图片描述
初级写法 :输入1000循环500500次

#include<stdio.h>
int main() {
    long a, b, c;
    long t = 0;
    //c^2=a^2+b^2可能溢出
    int n = 0;
    scanf("%d", &n);
    for (a = 0; a < n; a++)
        for (b = 0; b < n - a; b++) {
            c = n - a - b;
            if (a < b && b < c && a * a + b * b == c * c)
                printf("%d\n", a * b * c);
            t++;
        }
    printf("%d", t);
    return 0;
}

优化后的写法:输入1000循环139276次

#include<stdio.h>
int main()
{
    int n, a, b, c, k, i = 0;
    long t = 0;
    scanf("%d", &n);
    //因为c是最大的,不妨令a<b
    for (a = 1; a < n / 3; a++)
    {
        for (b = a + 1, k = n - 2 * a; b < k; b++) 
        
        {
            c = n - a - b;
            t++;
            if (a * a + b * b == c * c) {
                printf("%d\n", a * b * c);
                break;
            }
        }
        if (b < k)
           break;
        //此处if语句针对的是后续循环,一旦找到便无需继续循环
    }
    printf("%d", t);
    return 0;
}

优化思路:题目中没有明确规定a与b的大小,导致在初级写法中有多次重复循环,降低效率。可以假设a<b<c,并通过a+b+c=n,a,b均小于c给两次for循环中的判定条件进行优化,减少循环次数。


数列问题

有一个数列:1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6……
输入n,输出该数列中的第n项。

本题重点在于对数列形式的判断和转换,可以将其转换为:
1
1 2
1 2 3
1 2 3 4
…………
并由此编写程序
初级写法:输入144,循环143次
思路:a为行,第a行有a个数;b为列;c为架通a与n之间的桥梁

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int n, a = 1, b = 1, c = 1;
    scanf("%d", &n);
    int t = 0;
    while (c < n)
    {
        if (b < a)
        b++;
        else 
        b = 1, a++;
        c++;
        t++;
    }
    printf("%d\n", b);
    printf("%d", t);
    return 0;
}

优化后的写法:输入144,循环15次
思路:通过求从第1行到 第n位数 所在行及 其上一行 的项数和(sum1和sum0),来判断n所在行数,一步到位。

#include<stdio.h>
int main() {
	int n = 0;
	scanf("%d", &n);
	int j = 1;
	int sum0 = 0,sum1 = 0;
	int t = 0;
	while (n>0) {
		sum0 = ((1 + j) * j) / 2;
		sum1 = ((2 + j) * (j + 1)) / 2;
		//printf("%d\n", sum0);
		if (sum0<n && sum1>n)
			break;
		else if (sum0 == n)
			printf("%d", j);
		else
			j++;
		t++;
	}
	n -= sum0;
	printf("%d\n", n);
	printf("%d", t);
	return 0;
}

总结

目前的OJ题目都以基础算法为主,本文是基于我自身的判断与感受,期待能有路过的高人给予批评指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值