Article directory
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…