巧解数学问题——练习题链接及解答

1.引言

  为了更好的练习和巩固所学的知识,也会在其他OJ上找一些自己以前写过的题,供大家参考,附上链接和解答。

2.最大公约数与最小公倍数

PIPIOJ例题:1352.多个数的最小公倍数(简单)

#include<bits/stdc++.h>
using namespace std;

int GCD(int a, int b) {
	if (a % b == 0)return b;
	else return GCD(b, a % b);
}
int LCM(int a, int b) {
	return  a / GCD(a, b) * b;//这里需要注意a*b可能会超出数据范围 所以最后再乘b。
}
int main() {
	int t;
	cin >> t;
	while (t--) {
		int n,num,ans=1;
		cin >> n;
		for (int i = 0; i < n; i++) {
			cin >> num;
			ans = LCM(ans, num);
		}
		cout << ans << endl;
	}
	return 0;
}

3.筛法和打表

PIPIOJ例题:1044.七夕节(简单)
  如果单纯的枚举每一个数的因子的话,考虑到有T次查询,时间复杂度为O(T*N),会超时,所以不可取。下面给出两种常规解法:
  解法1:利用筛法的思想,先求出1~N每个数的所有因子和。

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int num[N];//num[i]表示i的所有因子和

int main() {
	int t;
	scanf("%d",&t);
	num[1] = 1;
	for (int i = 1; i < N; i++) {//枚举每一个因子
		for (int j = 2*i; j < N; j += i) {//包含因子i的数都加上i
			num[j] += i;
		}
	}
	while (t--) {
		int n;
		scanf("%d",&n);//这里注意用cin和cout的话会超时,scanf和printf比较快
		printf("%d\n",num[n]);
	}
	return 0;
}

  解法2:根号优化。对于一个数字N,只需要枚举sqrt(N)以内的因子factor,可以通过N/factor便可以得到大于等于sqrt(N)的另外一个成对的因子。这样一来时间复杂度就变为O(T*sqrt(n))。

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;

int main() {
	int t;
	scanf("%d",&t);
	while (t--) {
		int n,ans=1;
		scanf("%d",&n);
		int a=sqrt(n);
		for(int i=2;i<=a;i++){
			if(n%i==0){
				ans+=i;
				if(n/i!=i)ans+=n/i;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

4.进制转换

Leetcode例题:1017. 负二进制转换(中等)
  这里的余数有三种情况:-1,1,0,但是最终的答案只有1和0,所以在余数为1时,要单独处理一下:

string baseNeg2(int n) {//用短除法,参照十进制转二进制
        if(n==0)return "0";
        string ans;
        while(n){
            int remainder = n%(-2);//余数
            n = n/(-2);//商
            ans += '0'+abs(remainder);//余数为负1时,由于二进制字符串只有1和0,所以将余数变为1
            if(remainder<0){//余数从-1——>1,加了2,为了保持被除数不变,所以商加1,(被除数/除数=商+余数)
                n+=1;       // 被除数=商*除数+余数,商加1 等于余数+2(因为除数等于-2)
            }
        }
        reverse(ans.begin(),ans.end());
        return ans;
 }

未完待续…

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值