zoukankan      html  css  js  c++  java
  • 《程序设计语言综合设计》第三周上机练习

    4 回文数

    对于一个自然数n,若将n的各位数字反向排列所得的数n1与n相等,则称n为回文数,例如2332。
    若给定一个N( 2<=N<=16)进制数M(M的长度在一百位以内),如果M不是回文数,可以对其进行N进制加法,最终得到回文数。
    例如对于十进制数79 STEP1 : 79 + 97 = 176 STEP2 : 176 + 671 = 847 STEP3 : 847 + 748 = 1595 STEP4 : 1595 +5951 = 7546 STEP5 : 7546 + 6457 = 14003 STEP6 : 14003 + 30041 = 44044
    那么对于给定的N进制数M,请判断其能否在30步以内(包括30步)得到回文数。

    输入格式

    第一行包括一个正整数 N(2<=N<=16)。
    第二行包括一个正整数M(一百位以内)。

    输出格式

    如果可以在n步内得到回文数,输出“STEP=n”,否则输出“NO”。

    输入样例1

    10
    79

    输出样例1

    STEP=6

    输入样例2

    8
    665556

    输出样例2

    NO

    Accepted

    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string.h>
    using namespace std;
    void rever(string a){ //可用 reverse(a.begin(), a.end());代替
        int i,j;
        char temp;
        int len=(int)a.size()-1;
        if(len%2){
        for(i=0,j=len-1;i!=j;i++,j--){
            temp=a[i];
            a[i]=a[j];
           a[j]=temp;
          }
        }
        if(len%2==0){
        for(i=0,j=len-1;i!=j-1;i++,j--){
            temp=a[i];
            a[i]=a[j];
           a[j]=temp;
          }
        }
    }
    string sum_str(string m,int n){
        int temp = 0,i;
        int flag=0;
        string a;
        int j=(int)m.size()-1;
        for(i=0;i<m.size()&&j>=0;i++,j--){
            temp=0;
           if(m[i]>='0'&&m[i]<='9') temp+=(m[i]-'0');
            if(m[j]>='0'&&m[j]<='9') temp+=(m[j]-'0');
            if(m[i]>='A'&&m[i]<='Z')temp+=(m[i]-'A')+10;
            if(m[j]>='A'&&m[j]<='Z')temp+=(m[j]-'A')+10;
            if(flag==1){//进位1
                temp++;
                 flag=0;
            }
            if(temp>=n){//大于n要进位
                flag=1;
                temp-=n;}
            if(temp<10) temp+='0';
            else temp=temp-10+'A';
              a+=temp;
        }
        if(flag==1){
            a=a+"1";
        }
          rever(a);
        return a;
    }
    int judge(string m){
        int i,j;
        for(i=0,j=(int)m.size()-1;i<m.size()&&j>=0;i++,j--){
            if(m[i]!=m[j]) return 0;
        }
        return 1;
    }
    int main() {
        int n;
        int step=0;
        string m;
        cin >> n;
        cin >> m;
        if(judge(m)) cout << "STEP=" <<step << endl;
        else{
            while(step<=30){
                m=sum_str(m,n);
                step++;
                
                if(judge(m)){
                    cout << "STEP=" <<step << endl;
                    break;
                }
            }
        }
        if(step>30) {cout << "NO" << endl; }
        return 0;
    }
    
    

    高精度计算加减乘除

    5 数楼梯

    楼梯有N阶,上楼可以一步上一阶,也可以一步上两阶。那么走到第N阶楼梯共有多少种不同的走法呢?

    输入格式

    一个正整数 N(1<=N<=5000),表示楼梯阶数。

    输出格式

    输出一个数,表示走到第N阶楼梯有多少种走法。
    注意,数据范围很大,即使是64位也可能不够存。

    输入样例1

    4

    输出样例1

    5

    输入样例2

    400

    输出样例2

    28481229810848961175798893768146099561538008878230489098647719564596927140403

    Accepted
    (来源:洛谷)

    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string.h>
    using namespace std;
    int len=1,fl[5005][5005]={0};//fl[k][i]--第k阶台阶所对应的走法数
    void floor(int k){
        int i;
        for(i=1;i<=len;i++)
            fl[k][i]=fl[k-1][i]+fl[k-2][i];
        for(i=1;i<=len;i++){
            if(fl[k][i]>=10){
                fl[k][i+1]+=fl[k][i]/10;
                fl[k][i]=fl[k][i]%10;
                if(fl[k][len+1]) len++;
            }
        }
    }
    int main() {
        int n;
        cin >> n;
        fl[1][1]=1;
        fl[2][1]=2;
        for(int i=3;i<=n;i++){
            floor(i);
        }
        for(int i=len;i>=1;i--){
            printf("%d",fl[n][i]);
        }
        return 0;
    }
    

    这道题我们可以论述一下递推与递归的方法与区别

    递推一般用循环来解决,从已知条件到未知逐渐接近结果:
    (1)将复杂运算分解为若干重复的简单运算
    (2)后一步骤建立在前一步骤之上
    (3)计算每一步骤的方法相同
    (4)从开始向后计算出结果
    (5)使用循环结构,通过多次循环逐渐逼近结果
    递归一般自己调用自己,从未知到已知,把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。
    (1)每一次递归都缩小问题规模,直到问题足够小
    (2)使用选择分支语句
    (3)从后往开始逐步逼近
    (4)达到最开始,再把初始值带入往后逐一求解

    6 A-B

    已知两个数A和B,求A-B的运算结果。

    输入格式

    输入包括两个正整数A和B 。(0<A,B≤1e10086)

    输出格式

    输出A-B的运算结果。

    输入样例1

    3
    2

    输出样例1

    在这里给出相应的输出。例如:
    1

    输入样例2

    11102356985410
    2356985410235698

    输出样例2

    在这里给出相应的输出。例如:
    -2345883053250288

    Wrong Answer

    给出我的比较麻烦的代码(只有90分,待修改)

    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string.h>
    using namespace std;
    int sign=0;
    string sub(string a,string b){
        string ans;
        int temp;
        long  long lena=(int)a.size();
        long long lenb=(int)b.size();
         reverse(a.begin(), a.end());
         reverse(b.begin(), b.end());
        long long i;
        int flag=0;
        if(lena<lenb){
            sign=1;
            for(i=0;i<lenb;i++){
                int at=0,bt=0;
                if(a[i]>='0'&&a[i]<='9') at=a[i]-'0';
                if(b[i]>='0'&&b[i]<='9') bt=b[i]-'0';
               temp=bt-at;
                if(flag==1) {
                    temp--;
                    flag=0;
                }
                if(temp<0){
                    temp+=10;
                    flag=1;
                }
                ans+=temp+'0';
            }
            // if(temp<0) sign=1;
        }
        if(lena==lenb){
             if(a<b)  sign=1;
            if(sign){
            for(i=0;i<lenb;i++){
                int at=0,bt=0;
                if(a[i]>='0'&&a[i]<='9') at=a[i]-'0';
                if(b[i]>='0'&&b[i]<='9') bt=b[i]-'0';
                temp=bt-at;
                if(flag==1) {
                    temp--;
                    flag=0;
                }
                if(temp<0){
                    temp+=10;
                    flag=1;
                }
                ans+=temp+'0';
            }
                  // if(temp<0) sign=1;
            }
            else{
                for(i=0;i<lena;i++){
                    int at=0,bt=0;
                    if(a[i]>='0'&&a[i]<='9') at=a[i]-'0';
                    if(b[i]>='0'&&b[i]<='9') bt=b[i]-'0';
                     temp=at-bt;
                    if(flag==1) {
                        temp--;
                        flag=0;
                    }
                    if(temp<0){
                        temp+=10;
                        flag=1;
                    }
                    ans+=temp+'0';
                }
                //if(temp<0) sign=1;
            }
        }
        if(lena>lenb){
               for(i=0;i<lena;i++){
                   int at=0,bt=0;
                   if(a[i]>='0'&&a[i]<='9') at=a[i]-'0';
                   if(b[i]>='0'&&b[i]<='9') bt=b[i]-'0';
                  temp=at-bt;
                   if(flag==1) {
                       temp--;
                       flag=0;
                   }
                   if(temp<0){
                       temp+=10;
                       flag=1;
                   }
                   ans+=temp+'0';
               }
           //  if(temp<0) sign=1;
           }
        reverse(ans.begin(), ans.end());
        return ans;
    }
    int main() {
        string a,b;
        string ans;
        int flag=0;
        cin >> a;
        getchar();
        cin >> b;
        getchar();
        if(a==b) {
            cout << "0" << endl;
            return 0;
        }
        ans=sub(a,b);
        if(sign) cout <<"-";
        for(long long i=0;i<ans.size();i++){
            if(flag==0&&ans[i]!='0'){
                cout << ans[i];
                flag=1;
            }
            else if(flag==1){
                cout << ans[i];
            }
        }
        return 0;
    }
    
    

    后来询问发现,第一版错的原因在于当两个数长度不相等时,未对数字进行相应的初始化。
    更改后终于AC:

    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string.h>
    using namespace std;
    int sign=0;
    string sub(string a,string b){
        string ans;
        int lena=(int)a.size();
        int lenb=(int)b.size();
         reverse(a.begin(), a.end());
         reverse(b.begin(), b.end());
        int i;
        int flag=0;
        if(lena<lenb){
            sign=1;
            for(i=lena;i<lenb;i++){
                       a+='';
                   }
            for(i=0;i<lenb;i++){
                int at=0,bt=0;
                if(a[i]>='0'&&a[i]<='9') at=a[i]-'0';
                if(b[i]>='0'&&b[i]<='9') bt=b[i]-'0';
                int temp=bt-at;
                if(flag==1) {
                    temp--;
                    flag=0;
                }
                if(temp<0){
                    temp+=10;
                    flag=1;
                }
                ans+=temp+'0';
            }
        }
        if(lena==lenb){
             if(a<b)  sign=1;
            if(sign){
            for(i=0;i<lenb;i++){
                int at=0,bt=0;
                if(a[i]>='0'&&a[i]<='9') at=a[i]-'0';
                if(b[i]>='0'&&b[i]<='9') bt=b[i]-'0';
                int temp=bt-at;
                if(flag==1) {
                    temp--;
                    flag=0;
                }
                if(temp<0){
                    temp+=10;
                    flag=1;
                }
                ans+=temp+'0';
            }}
            else{
                for(i=0;i<lena;i++){
                    int at=0,bt=0;
                    if(a[i]>='0'&&a[i]<='9') at=a[i]-'0';
                    if(b[i]>='0'&&b[i]<='9') bt=b[i]-'0';
                    int temp=at-bt;
                    if(flag==1) {
                        temp--;
                        flag=0;
                    }
                    if(temp<0){
                        temp+=10;
                        flag=1;
                    }
                    ans+=temp+'0';
                }
            }
        }
        if(lena>lenb){
            for(i=lenb;i<lena;i++){
                b+=' ';
            }
               for(i=0;i<lena;i++){
                   int at=0,bt=0;
                   if(a[i]>='0'&&a[i]<='9') at=a[i]-'0';
                   if(b[i]>='0'&&b[i]<='9') bt=b[i]-'0';
                   int temp=at-bt;
                   if(flag==1) {
                       temp--;
                       flag=0;
                   }
                   if(temp<0){
                       temp+=10;
                       flag=1;
                   }
                   ans+=temp+'0';
               }
           }
        reverse(ans.begin(), ans.end());
        return ans;
    }
    int main() {
        string a={0},b={0};
        string ans;
        int flag=0;
        cin >> a;
        getchar();
        cin >> b;
       // getchar();
        if(a==b) {
            cout << "0" << endl;
            return 0;
        }
        ans=sub(a,b);
        if(sign) cout <<"-";
        for(int i=0;i<ans.size();i++){
            if(flag==0&&ans[i]!='0'){
                cout << ans[i];
                flag=1;
            }
            else if(flag==1){
                cout << ans[i];
            }
        }
        return 0;
    }
    
    

    Accepted
    (来源:大数减法)

    第二版更加简练,把判断的部分放在main函数中,且AC了

    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string.h>
    using namespace std;
    string sub(string a,string b,int len){
        int i;
        string ans;
        int lenb=(int)b.size();
        for(i=0;i<lenb;i++){
            if(a[i]>=b[i]){ //不需要向前借1
                ans+=a[i]-b[i]+'0';
            }
            else{//需要向前借1
                ans+=a[i]+10-b[i]+'0';
                a[i+1]--;
            }
        }
        for(;i<len;i++){
            ans+=a[i];
        }
          reverse(ans.begin(), ans.end());
        return ans;
    }
    int main() {
        string a,b;
        string ans;
        int i;
        int flag=0;
        cin >> a >> b;
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        int lena=(int)a.size();
        int lenb=(int)b.size();
        if(lena>lenb){ ////若减数长度 > 被减数长度,正常减
            ans=sub(a,b,lena);
            for(i=0;i<ans.size();i++){
                if(flag==0&&ans[i]>'0'&&ans[i]<='9')   {
                    cout << ans[i];
                    flag=1;
                }
                else if(flag==1) cout << ans[i];
            }
            return 0;
        }
        else if(lena<lenb){//若减数长度 < 被减数长度,被减数-减数
            cout <<"-";
            ans=sub(b,a,lenb);
            for(i=0;i<ans.size();i++){
                        if(flag==0&&ans[i]>'0'&&ans[i]<='9')   {
                                     cout << ans[i];
                                     flag=1;
                                 }
                       else if(flag==1) cout << ans[i];
                   }
            return 0;
        }
        else{//若减数长度 == 被减数,判断两个数的大小
            
            if(a>b){
                ans=sub(a,b,lena);
                 for(i=0;i<ans.size();i++){
                             if(flag==0&&ans[i]>'0'&&ans[i]<='9')   {
                                         cout << ans[i];
                                         flag=1;
                                     }
                           else if(flag==1) cout << ans[i];
                       }
            }
            else if(a<b){
                cout <<"-";
                ans=sub(b,a,lenb);
                 for(i=0;i<ans.size();i++){
                             if(flag==0&&ans[i]>'0'&&ans[i]<='9')   {
                                         cout << ans[i];
                                         flag=1;
                                     }
                           else if(flag==1) cout << ans[i];
                       }
            }
            else{
                cout << "0" << endl;
            }
        }
        return 0;
    }
    
    

    7 高精度除法

    给两个正整数 a,b,求 a/b的整数部分。

    输入格式

    输入共两行,每行一个正整数,分别表示 a和b。 50%数据,a,b均小于1e18, 50%数据,a,b均小于1e500。

    输出格式

    输出一个整数,表示a/b的整数部分。

    输入样例1

    3
    2

    输出样例1

    1

    输入样例

    24781236498237462378425347823652387423654238752372365327862
    8934457724628746

    输出样例2

    2773669903874014740488146558678531750078864

    Accepted
    (来源:大数除法)

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int L=11000;
    int sub(int *a,int *b,int lena,int lenb)
    {
        if(lena<lenb) return -1;//如果a小于b,则返回-1
        if(lena==lenb)
        {
            for(int i=lena-1;i>=0;i--)
                if(a[i]>b[i]) break;
                else if(a[i]<b[i]) return -1;//如果a小于b,则返回-1
     
        }
        for(int i=0;i<lena;i++)//高精度减法
        {
            a[i]-=b[i];
            if(a[i]<0) {a[i]+=10;a[i+1]--;}
        }
        for(int i=lena-1;i>=0;i--)
            if(a[i]) return i+1;//返回差的位数
        return 0;//返回差的位数
     
    }
    string div(string n1,string n2)//n1,n2是字符串表示的被除数
    {
        string s,v;//s存商,v存余数
        int a[L]={0},b[L]={0},r[L]={0},lena=n1.size(),lenb=n2.size(),i;//a,b是整形数组表示被除数,除数
         for(i=lena-1;i>=0;i--) a[lena-1-i]=n1[i]-'0';
         for(i=lenb-1;i>=0;i--) b[lenb-1-i]=n2[i]-'0';
         if(lena<lenb || (lena==lenb && n1<n2)) {
         return "0";
         }//如果a<b,则商为0
         int t=lena-lenb;//除被数和除数的位数之差
         for(int i=lena-1;i>=0;i--)//将除数扩大10^t倍
            if(i>=t) b[i]=b[i-t];
            else b[i]=0;
         lenb=lena;
         for(int j=0;j<=t;j++)
         {
             int temp;
             while((temp=sub(a,b+j,lena,lenb-j))>=0)//如果被除数比除数大继续减
             {
                 lena=temp;
                 r[t-j]++;
             }
         }
        for(i=0;i<L-10;i++) {r[i+1]+=r[i]/10;r[i]%=10;}//统一处理进位 ??
         while(!r[i]) i--;//将整形数组表示的商转化成字符串表示的
         while(i>=0) s+=r[i--]+'0';
         return s;
         
    }
    int main()
    {
        string a,b;
        cin>>a>>b;
        cout<<div(a,b)<<endl;
        return 0;
    }
    
  • 相关阅读:
    httphelper
    MD5加密
    json操作
    将list转成tree
    GenerateId类:生成唯一id、订单号
    加密、解密(默认密钥向量)
    Hadoop HDFS批量处理
    OceanBase学习总结
    TiDB学习
    开机自启动rc.local文件修改权限
  • 原文地址:https://www.cnblogs.com/lvhang/p/12441090.html
Copyright © 2011-2022 走看看