第26题
这一题是求
1i,∀i∈[2,1000)
的所有结果的十进制小数表示下具有最长循环节的
i
。
我将在我的算法中定义有限小数也是循环节为1的循环小数,例如
回忆列竖式的过程,不太会用mathtype,没对齐,不过应当容易看懂。
在竖式的最后一行,我们出现了10,而10已经在竖式中出现过一次了,那么这就是一个循环节了。
我们在程序中模拟做竖式的过程,每次将(余数*10)加入set,若过程中发现该结果已经在set中了,则得到循环节长度。利用max_element输出最大值即可。
代码如下:
set<int> s[1000];
int len[1000];
int main(){
int n=1000;
for (int i=1;i<n;i++){
int remain=1;
while(s[i].count(remain)==0){
s[i].insert(remain);len[i]++;
remain=(remain%i)*10;
}
}
cout<<*max_element(len,len+n)<<endl;
return 0;
}
第27题
这个题是寻找函数
f(n)=n2+an+b
的一组
(a,b)
,满足
f(n)=prime,∀n∈[0,x)
,若
|a|<1000,|b|<1000
,求当
x
取得最大值时的
我没有想到很好的剪枝方法。我的思路是由于
f(0)=prime=b
,所以
b
一定是质数。
int main(){
cnt=0;
for (int i=2;i<=maxn;i++){
if (num[i]==0) p[++cnt]=i;
for (int j=1;j<=cnt&&p[j]*i<maxn;j++){
num[p[j]*i]=1;
}
}
int maxx=0,ans=0;
for (int a=-999;a<=999;a++){
for (int index=1,b=p[index];b<=1000;index++,b=p[index]){
if(a+b>=2){
int tmp=cal(a,b);
if (maxx<tmp) {
maxx=tmp,ans=a*b;
}
}
}
}
cout<<ans<<endl;
return 0;
第28题
这个题是求1001*1001大小的方阵中,各数字如图排列,求对角线和。
除最中心的1以外,第i圈第j位置的数x与第i-1圈对应位置的数y的关系是
x=y+i∗8−2∗j
,其中将右上、左上、左下、右下的位置依次记为0,1,2,3;
而通过循环递推来完成更容易实现,记录一个add变量,每次将内圈的值加上add就得到了外圈的值。add每次自增2;
int main(){
int f[4]={1,1,1,1};
long long ans=1,n=500;
for (int i=1,add=2;i<=n;i++){
for (int j=0;j<4;add+=2,j++){
f[j]+=add;
ans+=f[j];
}
}
cout<<ans<<endl;
return 0;
}
第29题
题意如图。
求出所有的
(xymod1000000007,xymod1000000009)
,可以通过递推实现,将数对塞入set,最后统计set的元素个数。
pair<long long,long long>num[110][110];
long long mod1=1e9+7,mod2=1e9+9;
set<pair<long long,long long> > s;
int main(){
int n=100;
for (int i=2;i<=n;i++){
num[i][1].first=num[i][1].second=i;
for (int j=2;j<=n;j++){
num[i][j].first=num[i][j-1].first*i%mod1;
num[i][j].second=num[i][j-1].second*i%mod2;
s.insert(num[i][j]);
}
}
cout<<s.size()<<endl;
return 0;
}
第30题
求所有除一以外自身等于各位数字的五次方和的数的和。考虑到 99=59049 ,所以满足条件的数一定小于 5∗99=295245 。枚举每个数验证即可,复杂度 O(nlogn)
int check(int num){
int ans=0;
while(num){
int x=num%10;
ans+=x*x*x*x*x;
num/=10;
}
return ans;
}
int main(){
int ans=0;
for (int i=2;i<=295245;i++){
if (check(i)==i) ans+=i;
}
cout<<ans<<endl;
return 0;
}