高精乘:一位乘多位

高精乘:一位乘多位

——比较简单的高精乘,为多位乘多位做铺垫

T1:国王与麦子

题目描述
传说古代印度有个喜欢下棋的国王叫舍罕,而宰相达依尔是个聪明的大臣,发明了国际象棋。国王玩得爱不惜手,决定奖赏宰相。达依尔说:陛下,我别无他求,请你在这张棋盘的第一个格子里赏我一粒麦子;在第2个格子里赏我2粒麦子;在第3个格子里赏我4粒麦子;在第4个格子里赏我8粒麦子……依此类推直到64个格子,按这张棋盘上各格应赏的麦子全赏给我吧。
国王听了,觉得达依尔的要求并不高,说道:你能如愿以偿的。然而,国王却不知道这个数字是多么巨大啊!
你能帮助国王算算第n个格子的麦子数量吗?
输入
一个正整数n(n<=100)。
输出
一个数,表示第n个格子的麦子数
输入样例 复制
5
输出样例 复制
16

思路

题意很简单读懂,思路也很简单,for循环乘2就行了,主要是考察高精多位乘单位。

代码

#include<iostream>
#include<cstring>
using namespace std;
string ans="1";
int n,x[500],y[500];
int main()
{
    cin>>n;
    for(int j=2;j<=n;j++)
    {
        memset(y,0,sizeof(y));
        memset(x,0,sizeof(x));      
        for(int i=0;i<ans.size();i++)
        {
            x[ans.size()-i]=int(ans[i])-48;
        }
        int c=ans.size();
        for(int i=1;i<=c;i++)
        {
            y[i]+=x[i]*2;
            if(y[i]>=10)
            {
                y[i+1]++;
                y[i]%=10;
            }
        }
        if(y[c+1]!=0)
        {
            c++;
        }
        ans="";
        for(int i=c;i>=1;i--)
        {
            ans+=char(y[i]+48);
        }
    }
    cout<<ans;
    return 0;
}

总结

第一次用高精乘,觉得有点麻烦,代码比较长。这里高精乘最多进一位,所以不需要很多的处理。

T2:乘积根

题目描述
一个整数的数字乘积根是这样得到的:将此整数中的非零数字相乘,得到的结果再重复上述运算,直到只有一位数为止,此一位数即为原整数的数字乘积根。

   例如:整数 99 , 99--> 9*9=81-->8*1=8 , 8 即为 99 的乘积根。

输入
一个n位的整数(n<=255)。
输出
有若干行,每行显示每次数字相乘之后的结果,最后一行只有一个一位数,即为n的乘积根。
输入样例 复制
【输入样例1】
99

【输入样例2】
1203
输出样例 复制
【输出样例1】
81
8

【输出样例2】
6

思路

相对上一题不过是多了拆分和,要注意的是,这里不仅会进一位,会进很多位,要用除和mod来处理。

代码

#include<bits/stdc++.h>
using namespace std;
string a;
string ch(string n)
{
    int m[300],q[300],p[300];
    string ans1="1";
    memset(m,0,sizeof(m));
    for(int i=0;i<n.size();i++)
    {
        m[n.size()-i]=n[i]-48;
    }
    
    for(int j=1;j<=n.size();j++)
    {
        if(m[j]==0) continue;
        memset(p,0,sizeof(p));
        memset(q,0,sizeof(q));
        for(int i=0;i<ans1.size();i++)
        {
            q[ans1.size()-i]=ans1[i]-48;
        }   
        int c=ans1.size();
        for(int i=1;i<=c;i++)
        {
            p[i]+=m[j]*q[i];
            if(p[i]>=10)
            {
                p[i+1]+=p[i]/10;
                p[i]%=10;
            }
        }
        if(p[c+1]!=0)
        {
            c++;
        }
        ans1="";
        for(int i=c;i>=1;i--)
        {
            ans1+=char(p[i]+48);
        }
    }
    return ans1;
}
int main()
{
    cin>>a;
    if(a.size()==1)
    {
        cout<<a;
        return 0;
    }
    while(a.size()!=1)
    {
        a=ch(a);
        cout<<a<<endl;
    }
    return 0;
}

总结

也是一道很麻烦的题,注意输入后要特判,不然不会进循环就不会有输出了。

T3:阶乘和

题目描述
已知正整数n(n<=200),请编程计算 1!+2!+…+n! 的值。

注:n!=1 * 2 *… * (n-1) * n。

输入
一个正整数n(n<=200)。
输出
一行,表示阶乘和。
输入样例 复制
4
输出样例 复制

思路

题意很简单,不需要什么思路,就是高精乘和加的结合,特别麻烦。

代码

#include<bits/stdc++.h>
using namespace std;
int a;
string ans="";
string jc(int n)
{
    int q[400],p[400];
    string ans1="1";
    for(int j=1;j<=n;j++)
    {
        memset(p,0,sizeof(p));
        memset(q,0,sizeof(q));
        for(int i=0;i<ans1.size();i++)
        {
            q[ans1.size()-i]=ans1[i]-48;
        }   
        int c=ans1.size();
        for(int i=1;i<=c;i++)
        {
            p[i]+=j*q[i];
            if(p[i]>=10)
            {
                p[i+1]+=p[i]/10;
                p[i]%=10;
            }
        }
        if(p[c+1]!=0)
        {
            while(p[c+1]!=0)
            {
                c++;
                p[c+1]=p[c]/10;
                p[c]%=10;
            }
        }
        ans1="";
        for(int i=c;i>=1;i--)
        {
            ans1+=char(p[i]+48);
        }
    }
    return ans1;
}
string jia(string a,string b)
{
    int x[500],y[500],z[500];
    memset(x,0,sizeof(x));
    memset(y,0,sizeof(y));
    memset(z,0,sizeof(z));
    for(int i=0;i<a.size();i++)
    {
        x[a.size()-i]=int(a[i])-48;
    }
    for(int i=0;i<b.size();i++)
    {
        y[b.size()-i]=int(b[i])-48;
    }
   long long c=max(a.size(),b.size());
    for(int i=1;i<=c;i++)
    {
        z[i]+=x[i]+y[i];
        if(z[i]>=10)
        {
            z[i+1]++;
            z[i]%=10;
        }
    }
    while(z[c+1]!=0)
            {
                c++;
                z[c+1]=z[c]/10;
                z[c]%=10;
            } 
    string giao;
    giao="";
    for(int i=c;i>=1;i--)
    {
        giao+=char(z[i]+48);
    }
    return giao;
}
int main()
{
    cin>>a;
    for(int i=1;i<=a;i++)
    {
        ans=jia(ans,jc(i));
    }
    cout<<ans;
    return 0;
}

总结

麻烦到一种境界,我也是硬敲了八十多行才过得。注意它最后不只会进一位,要用while循环进位。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值