Solve Math Problems Cleverly——Exercise Links and Answers

1 Introduction

  In order to better practice and consolidate the knowledge I have learned, I will also find some questions I have written before on other OJs for your reference, with links and answers attached.

2. Greatest common divisor and least common multiple

PIPIOJ example: 1352. Least common multiple of multiple numbers (simple)

#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. Screening and tabulation

PIPIOJ sample question: 1044. Qixi Festival (simple)
  If you simply enumerate the factors of each number, considering that there are T queries, the time complexity is O(T*N), and it will time out, so it is not advisable. Two conventional solutions are given below:
  Solution 1: Using the idea of ​​​​the sieve method, first find the sum of all factors of each number from 1 to 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;
}

  Solution 2: root sign optimization. For a number N, you only need to enumerate the factor factor within sqrt(N), and you can get another paired factor greater than or equal to sqrt(N) through N/factor. In this way, the time complexity becomes 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. Base conversion

Leetcode example: 1017. Negative binary conversion (medium)
  There are three situations for the remainder here: -1, 1, 0, but the final answer is only 1 and 0, so when the remainder is 1, it must be dealt with separately:

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;
 }

To be continued…

Guess you like

Origin blog.csdn.net/Ratib/article/details/129736435