题目粗心:

给出一个长度不超过20的整数,问这个整数乘以2当前的数位是否为原数数位的一个排列

算法思路:

因为长度有可能达到20位,超过了long long的存储范畴,所以这里采纳string存储输出的整数。该题只须要解决两个问题,第一个就是如何判断2个整数的互为排列,第二个就是如何计算一个字符串与2的乘法。解决第一个问题的思路就是利用hash映射的思维,利用countOfS存储0~9数字呈现的次数,在输出的时候做加法,对于输出的数字s的每一位s[i],++countOfS[s[i]-'0'],在做完乘法后失去数字r,而后对r的每一个数字r[k]做减法,--countOfS[r[k]-'0'];如果减完后呈现小于0的状况就阐明这两个不是互为排列并且应用isTrue记录下来。第二个问题的解决思路就是应用指针j对s从后向前扫描,并且应用carry记录上一位的进位,对于每一位数字s[j],都乘以2而后加上进位carry,(s[j]-'0')*2 + carry,该后果应用multi保留,而后计算进位multi/10,并将本位应用r保留,r += to_string(multi%10);最初依据isTrue是否为true输入YesNo,而后再输入逆置后的r即可。

留神点:

1、在进行乘法运算的时候,最高位如果有进位的化,也就是carry在退出循环后不为0得再增加到r中,测试点2和测试点7考查。

提交后果:

AC代码:

#include <cstdio>#include <string>#include <iostream>#include <algorithm>using namespace std;int main(){    string s;    cin>>s;    int countOfS[11] = {};// 统计s中每一个数字呈现的次数    for (int i = 0; i < s.size(); ++i) {        ++countOfS[s[i]-'0'];    }    // 将s乘以2    string r;    int carry = 0;    int multi;// 局部乘积    for (int j = s.size()-1; j >=0 ; --j) {        multi = (s[j]-'0')*2 + carry;        carry = multi/10;        r += to_string(multi%10);    }    // 最高位还有进位    if(carry!=0){        r += to_string(carry);    }    reverse(r.begin(),r.end());    bool isTrue = true;    for (int k = 0; k < r.size(); ++k) {        --countOfS[r[k]-'0'];        if(countOfS[r[k]-'0']<0){            isTrue = false;            break;        }    }    if(isTrue){        printf("Yes\n");    } else {        printf("No\n");    }    printf("%s",r.c_str());    return 0;}