021 Amicable numbers (开启传送门)。
题意:让你找到所有符合 d(d(n))==n d ( d ( n ) ) == n && d(n)≠n d ( n ) ≠ n 的和。其中 d(n) d ( n ) 为 n n 的除本身外所有的因子和。
分析:直接求出每个数的因子和,然后判断就行。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxm = 1e4+10;
long long sum[maxm];
void init(){
for(int i = 1;i<maxm;i++){
for(int j = i;j<maxm;j+=i){
sum[j]+=i;
}
sum[i]-=i;
}
}
int main() {
init();
long long ans = 0;
for(long long i = 220;i<=10000;i++){
if(sum[i]<maxm&&sum[sum[i]]==i&&sum[i]!=i) ans+=i;
}
cout<<ans<<endl;
return 0;
}
022 Names scores (开启传送门)。
题意:结构体排序计算。
分析:按照题意给的意思直接计算即可。涉及文件操作,就不贴代码了。
答案:871198282
023 Non-abundant sums(开启传送门)。
题意:类比于完全数,定义出了盈数,问你所有不能用两个盈数表示的数的和。
分析:题目中告诉了,所有不能用两个盈数表示的数不超过28123。所以我们预处理出所有的盈数,然后处理出所有符合要求的数,求和即可。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxm = 28124;
int num[maxm];
int flag = 0;
int cho[maxm];
bool can[maxm];
int main() {
// freopen("in.txt","r",stdin);
memset(num,0,sizeof(num));
for(int i = 1;i<maxm;i++){
for(int j = i;j<maxm;j+=i){
num[j]+=i;
}
num[i]-=i;
}
for(int i = 1;i<maxm;i++){
if(num[i]>i){
cho[flag++] = i;
}
}
for(int i = 0;i<flag;i++){
for(int j = i;j<flag;j++){
if(cho[i]+cho[j]<maxm){
can[cho[i]+cho[j]] = true;
}
}
}
long long ans = 0;
for(int i = 1;i<maxm;i++){
if(can[i]) continue;
ans+=i;
}
cout<<ans<<endl;
return 0;
}
024 Lexicographic permutations(开启传送门)。
题意:问你0-9构成的全排列中第1000000个排列是多少。
分析:如果只是为了答案,一个比较容易的做法是直接调用next_permutation函数1000000次就行了,但是正解应该是二分每一位,因为每一个确定的排列,都可以算出他是第几个排列,然后就可以得到答案。
代码:(调用函数)
#include <bits/stdc++.h>
using namespace std;
int num[10] = {0,1,2,3,4,5,6,7,8,9};
int main() {
// freopen("in.txt","r",stdin);
int ans = 0;
do{
ans++;
if(ans==1000000) break;
}while(next_permutation(num,num+10));
for(int i = 0;i<10;i++){
cout<<num[i];
}
cout<<endl;
return 0;
}
025 1000-digit Fibonacci number (开启传送门)。
题意:问你Fibonacci数列中,第几个位数大于等于1000.
分析:一个比较暴力的做法是直接用大数算出前面几千项,然后看你一下答案就行。但是一个更推荐的做法是:推公式,因为我们能知道第项的大小,因为有通项公式,然后就是对10取log就行了。
代码:(暴力做法)
BigInteger num[3];
int main() {
// freopen("in.txt","r",stdin);
num[1] = 1;
num[2] = 1;
int now = 0;
int ind = 3;
while(1){
num[now] = num[(now+1)%3]+num[(now+2)%3];
// cout<<num[now].tostring()<<endl<<endl;
if(num[now].length>999){
cout<<ind<<endl;
break;
}
now = (now+1)%3;
ind++;
}
return 0;
}