Have Fun with Numbers
解答:
用哈希表来表示一个数字映射这个数字的个数,当然也也可以用一个数组来存放0-9的个数,但是用哈希表时只用判断哈希表是否为空,如果用数组就要遍历这个数组是否都为0
#include<iostream>
#include<unordered_map>
using namespace std;
unordered_map<int,int>Map;
int main(){
string Strnum;
int digit[21]={0};//最多20位,超过了longlong的范围(19位)
cin>>Strnum;
for(int i=0;i<Strnum.size();i++){
digit[i]=Strnum[Strnum.size()-i-1]-'0';//倒序放到数组中,忘:-'0'
Map[digit[i]]++;
}
//进行翻倍处理
int jw=0;//初始化个位时进位为0
for(int i=0;i<Strnum.size();i++){
digit[i]=digit[i]*2+jw;
//考虑进位
if(digit[i]>=10){
digit[i]-=10;//因为只有从0-9的数字,所以2倍只会产生10-18的数字,只需要-10
jw=1;//0-0进位最多为1
}else{
jw=0;
}
Map[digit[i]]--;
//如果这个数的个数全部被抵消了,就把这个数从哈希表中的映射关系消除
if(Map[digit[i]]==0) Map.erase(digit[i]);
}
if(jw==1){
digit[Strnum.size()]=1;//最高位进1
Map[digit[Strnum.size()]]--;//最高位1对应的个数-1
if(Map[digit[Strnum.size()]]==0) Map.erase(digit[Strnum.size()]);//如果1的个数减1后使1的个数为0,清除1的映射
}
if(Map.size()==0){
cout<<"Yes\n";
}else{
cout<<"No\n";
}
if(digit[Strnum.size()]==1)cout<<1;
for(int i=Strnum.size()-1;i>=0;i--) cout<<digit[i];
return 0;
}
对于当最高位还有进位就一定不满足题目条件的思考:
但这里如果不能将加入最高位进位1放入哈希表的操作取消,因为要通过哈希表是否为空来判断Yes与No的输出
改进jw==1(最高位还有进位)的部分如下:
int flag=0;
if(jw==1){
Map[Strnum.size()]=1;
flag=1;
}
if(Map.size()==0){
cout<<"Yes\n";
}else{
cout<<"No\n";
}
if(flag)cout<<1;
for(int i=Strnum.size()-1;i>=0;i--) cout<<digit[i];