藍橋杯-小計算器(模擬)

題意:

       模擬程序型計算器,依次輸入指令,可能包含的指令有


  1. 數字:'NUM X',X爲一個只包含大寫字母和數字的字符串,表示一個當前進制的數
  2. 運算指令:'ADD','SUB','MUL','DIV','MOD',分別表示加減乘,除法取商,除法取餘
  3. 進制轉換指令:'CHANGE K',將當前進制轉換爲K進制(2≤K≤36)
  4. 輸出指令:'EQUAL',以當前進制輸出結果
  5. 重置指令:'CLEAR',清除當前數字


  指令按照以下規則給出:
  數字,運算指令不會連續給出,進制轉換指令,輸出指令,重置指令有可能連續給出
  運算指令後出現的第一個數字,表示參與運算的數字。且在該運算指令和該數字中間不會出現運算指令和輸出指令
  重置指令後出現的第一個數字,表示基礎值。且在重置指令和第一個數字中間不會出現運算指令和輸出指令
  進制轉換指令可能出現在任何地方


  運算過程中中間變量均爲非負整數,且小於2^63。
  以大寫的'A'~'Z'表示10~35

 

代碼:https://blog.csdn.net/Dog_dream/article/details/88181923

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

string toAns(ll n,int ne){
    if(n==0) return "0";
    string str;
    while(n){ //想想10進制轉2進制 短除法 n進制的a轉m進制的b a模m加到答案上,a除以m 因爲a是十進制 比較容易算
        int tm=n%ne;
        if(tm<=9) str+='0'+tm;
        else str+='A'+tm-10;
        n/=ne;
    }
    reverse(str.begin(),str.end());
    return str;
}

ll toTen(string str,int ne){
    ll ans=0,arg=1;
    for(int i=str.size()-1;i>=0;--i){//想想2進制轉10進制
        if(str[i]<='9') ans+=(str[i]-'0')*arg;
        else ans+=(str[i]-'A'+10)*arg;
        arg*=ne;
    }
    return ans;
}
ll getOp(ll a,ll b,string op){
    if(op=="ADD") return a+b;
    else if(op=="SUB") return a-b;
    else if(op=="MUL") return a*b;
    else if(op=="DIV") return a/b;
    else return a%b;
}
int main(){
    int n;
    cin>>n;
    ll ans=0;
    int ne=10;
    string str,op;
    while(n--){
        cin>>str;
        if(str=="CLEAR") {str.clear();op.clear();}
        else if(str=="EQUAL") {op.clear();cout<<toAns(ans,ne)<<endl;}
        else if(str=="CHANGE") {cin>>ne;}
        else if(str=="NUM"&&op.empty()){cin>>str;ans=toTen(str,ne);}
        else if(str=="NUM"&&!op.empty()){cin>>str;ans=getOp(ans,toTen(str,ne),op);}
        else {op=str;} //把+-*/%都放到這個最後的else裏
    }
    return 0;
}

 

PS:我的30分代碼,不知道哪錯了...... 先放一放吧(上面的AC代碼 人家寫的確實思路清晰簡潔有序啊)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char s1[105],s2[105];
int t[105],a[105];
ll num[2],ans;
//WA1:如果沒有op,ans=num[0] 即便沒有進行運算,也可能直接輸出第1個數
void change(int n,int m){//n轉m
    int i,k,len=strlen(s1);
    for(i=0;i<len;++i) t[len-1-i]=s1[i]-(s1[i]<65?48:s1[i]<97?55:61);
    for(k=0;len;){
        for(i=len;i>0;--i){
            t[i-1]+=t[i]%m*n;//+=
            t[i]/=m;
        }
        a[k++]=t[0]%m;
        t[0]/=m;
        while(len&&!t[len-1]) --len;
    }
    s2[k]=0;
    for(int i=0;i<k;++i) s2[k-1-i]=a[i]+(a[i]<10?48:a[i]<36?55:61);
}
int main(){
    int T;
    scanf("%d",&T);
    bool flag=0;
    int k=10;
    string op,opp;
    while(T--){
        cin>>op;
        if(op=="CLEAR"){
            flag=0;
            ans=0;
            s1[0]=0;
            num[0]=num[1]=0;
        }else if(op=="NUM"){
            scanf("%s",s1);
            if(k!=10) change(k,10);
            else strcpy(s2,s1);
            for(int i=0;s2[i];++i){
                num[flag]=num[flag]*10+s2[i]-'0';
            }
            //cout<<"num flag="<<flag<<endl;
            //cout<<"num:"<<num[0]<<" "<<num[1]<<"\n";
            if(flag){
                //cout<<"num:"<<num[0]<<" "<<num[1]<<"\n";
                if(opp=="ADD") {ans=num[0]+num[1];}
                if(opp=="SUB") {ans=num[0]-num[1];}
                if(opp=="MUL") {ans=num[0]*num[1];}
                if(opp=="DIV") {ans=num[0]/num[1];}
                if(opp=="MOD") {ans=num[0]%num[1];}
                num[0]=ans;num[1]=0;
            }else ans=num[0];
        }else if(op=="CHANGE"){
            scanf("%d",&k);
        }else if(op=="EQUAL"){
            int i=0;
            char tmp[105];
            while(ans){
                tmp[i++]=ans%10+48;
                ans/=10;
            }
            int len=i;
            for(i=0;i<len;++i) {
                s1[len-1-i]=tmp[i];
                //cout<<s1[i];
            }
            s1[len]=0;
            change(10,k);
            printf("%s\n",s2);
            flag=0;
        }else{
            opp=op;
            flag=1;
        }
    }
}

 

改了一下,AC了,所以是在進制轉換後的處理出了錯,接口沒處理好

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//WA1:如果沒有op,ans=num[0] 即便沒有進行運算,也可能直接輸出第1個數
string toAns(ll n,int k){//10轉k
    if(!n) return "0";//0要特判哦!!! 不然你返回空串?
    string ans;
    while(n){
        if(n%k<10) ans+='0'+n%k;
        else ans+='A'+n%k-10;
        n/=k; //爲什麼直接除以10就可以了?爲什麼任意進制轉換 不可隨意丟掉最後一位?t[0]/=m 沒有丟掉最後一位啊 //淦,你果然寫錯了,所以你的質疑是對的
    }
    reverse(ans.begin(),ans.end());
    return ans;
}

ll toTen(string s,int k){
    ll base=1,ans=0;
    int len=s.size();
    for(int i=len-1;i>=0;--i){
        if(s[i]<='9') ans+=(s[i]-'0')*base;
        else ans+=(s[i]-'A'+10)*base;
        base*=k;
    }
    return ans;
}

int main(){
    int T;
    scanf("%d",&T);
    bool flag=0;
    int k=10;
    string op,opp;
    string a;
    ll ans=0;
    ll num[2]={0,0};
    while(T--){
        cin>>op;
        if(op=="CLEAR"){
            flag=0;
            ans=0;
            num[0]=num[1]=0;
        }else if(op=="NUM"){
            cin>>a;
            //cout<<"a:"<<a<<endl;
            num[flag]=toTen(a,k);
            //cout<<"1num:"<<num[0]<<" "<<num[1]<<"\n";
            if(flag){
                //cout<<"2num:"<<num[0]<<" "<<num[1]<<"\n";
                if(opp=="ADD") {ans=num[0]+num[1];}
                if(opp=="SUB") {ans=num[0]-num[1];}
                if(opp=="MUL") {ans=num[0]*num[1];}
                if(opp=="DIV") {ans=num[0]/num[1];}
                if(opp=="MOD") {ans=num[0]%num[1];}
                num[0]=ans;num[1]=0;
                flag=0;
            }else ans=num[0];
        }else if(op=="CHANGE"){
            scanf("%d",&k);
        }else if(op=="EQUAL"){
            cout<<toAns(ans,k)<<endl;
        }else{
            opp=op;
            flag=1;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章