第21题
这个题定义了一个函数
d(x)=∑divisori
,其中
divisori
是
x
的因子且
求小于10,000的所有满足
d(d(a))==a
的
a
的和。
首先求所有数不为本身的因子的和。如果一个数一个数去分解,复杂度将会是
然后枚举1至n的所有数
i
,判断
int d[10001];
int main(){
int n=10000;
for (int i=1;i<=n;i++){
for (int j=i*2;j<=n;j+=i){
d[j]+=i;
}
}
int ans=0;
for (int i=1;i<=n;i++){
if (d[i]!=i&&d[i]<=n&&d[d[i]]==i){
ans+=i;
}
}
cout<<ans<<endl;
return 0;
}
第22题
题目来源ProjectEuler
题中txt地址:https://projecteuler.net/project/resources/p022_names.txt
这个题是给你超过5000个名字(其实是5163个),将所有名字按字典序排序后,求 ∑orderi∗scorei ,其中 scorei 定义为名字中每个字母在26个字母表中的位置。
这道题最最坑爹的地方是,题中没有说明 orderi 是从0开始计数的
我原来想过使用hash的方法用整型表示每个名字的字典序的,但是没找到很好的hash函数。结果就只能每次直接比较名字的字典序,复杂度变成了 O(length∗nlogn) 的了。建议使用编辑器的替换功能将所有的引号和逗号替换成’\n’
struct Name{
char s[20];
int sum;
Name(){sum=0;}
}name[10500];
bool cmp(Name a,Name b){return strcmp(a.s,b.s)<0;}
int main(){
int cnt=-1;
freopen("in.txt","r",stdin);
while(scanf("%s",name[++cnt].s)!=EOF){
for (int i=0;name[cnt].s[i];i++){
name[cnt].sum+=name[cnt].s[i]-'A'+1;
}
}
sort(name,name+cnt+1,cmp);
long long ans=0;
for (int i=0;i<=cnt;i++){
ans+=i*name[i].sum;
}
cout<<ans<<endl;
return 0;
}
第23题
定义 abundant number为所有非己因数和大于自己的数。
题目中告知大于28213的所有数都可以表示成两个abundant number的和。
问所有正数中不能被表示成两个abundant number的数的和。
使用类似21题的做法,求出小于28213的所有数的非己因数和,将非己因数和大于自身的数加入到vector里面,做一个 O(n2) 的处理,求出这些数两两组合的和,打上标记。最后将所有未标记的数加起来。
int num[30000];
vector<int> v;
int isable[30000];
int main(){
int n=28123;
memset(num,0,sizeof(num));
memset(isable,0,sizeof(num));
for (int i=1;i<=n;i++){
for (int j=i*2;j<=n;j+=i){
num[j]+=i;
}
}
for (int i=1;i<=n;i++){
if (num[i]>i) {
v.push_back(i);
}
}
for (int i=0,maxn=v.size();i<maxn;i++){
for (int j=i;j<maxn&&v[i]+v[j]<=n;j++){
isable[v[i]+v[j]]=1;
}
}
int ans=0;
for (int i=1;i<=n;i++){
if (isable[i]==0) ans+=i;
}
cout<<ans<<endl;
return 0;
}
第24题
这个题是求0123456789这九个数在字典序下的第1,000,000个全排列
利用c++的next_permutation()函数循环999,999次即可。并且这一函数可以作用于char数组。
int main(){
char num[]={'0','1','2','3','4','5','6','7','8','9','\0'};
for (int i=1;i<1000000;i++){
next_permutation(num,num+10);
}
cout<<num<<endl;
return 0;
}
第25题
这个题是求第一个达到1000位十进制数的斐波那契项的下标。
1000位也就是
10999
数量级的。
利用long double可以记录
104932
的值,虽然有效数字较为有限,但足够应付这个题了。其他类型的范围可参考该博客——桑海的专栏
求斐波那契数列的每一项,直到结果大于
10999
。
int main(){
long double f1=1,f2=1,f=1;
int index=2;
long double maxx=1;
for (int i=1;i<=999;i++) maxx*=10;
for (;f<maxx;){
index++;
f=f1+f2;
f1=f2;f2=f;
}
cout<<index<<endl;
return 0;
}