1023 Have Fun with Numbers (20分)
参考柳神代码,柳神的代码写的也太秒了Orz。啊这明明是个\(20\)分的题,我为什么还要参考,菜的安详+_+ 。
题意
要求原数字乘\(2\)后的结果是原数字的一个重新排列,用\(cnt\)数组记录原数和新数的各位数字情况,最后只有\(cnt[1 \sim 9]\)全为0才代表新产生的数是原数的一个排列。
思路
首先,如果两个整数的长度不同,那么命题一定不成立,返回false;而当两个整数的长度相同时,可以开一个count数组,用来存放09中每个数字的出现次数。然后枚举两个整数的所有数位,对原整数中出现的数字,令对应的count值加1;对新整数中出现的数字,令对应的count值减1。如果在枚举完所有数位后,所有count数组元素的值均为0,说明新整数的数位是原整数数位的一个排列,返回true;只要09中有一个数字的出现次数不为0,则返回false。
代码
如果新产生的数的位数大于原数的位数即最高位仍然有进位,说明两个数的长度不同,也要输出\(No\)。
const int N=25;
char s[N];
int a[N],b[N];
int cnt[10];
int n;
int main()
{
scanf("%s",s);
n=strlen(s);
int t=0;
for(int i=n-1;i>=0;i--)
{
a[i]=s[i]-'0';
cnt[a[i]]++;
int x=a[i]*2+t;
b[i]=x%10;
cnt[b[i]]--;
t=x/10;
}
bool ok=true;
for(int i=0;i<10;i++)
if(cnt[i] != 0)
ok=false;
if(t || !ok) puts("No");
else puts("Yes");
if(t) cout<<1;
for(int i=0;i<n;i++) cout<<b[i];
cout<<endl;
//system("pause");
return 0;
}
当然,也可以用两个\(cnt\)数组分别记录,感觉更好理解一点。
const int N=25;
char s[N];
int a[N],b[N];
int cnta[10],cntb[10];
int n;
int main()
{
scanf("%s",s);
n=strlen(s);
int t=0;
for(int i=n-1;i>=0;i--)
{
a[i]=s[i]-'0';
cnta[a[i]]++;
int x=a[i]*2+t;
b[i]=x%10;
cntb[b[i]]++;
t=x/10;
}
bool ok=true;
for(int i=0;i<10;i++)
if(cnta[i] != cntb[i])
ok=false;
if(t || !ok) puts("No");
else puts("Yes");
if(t) cout<<1;
for(int i=0;i<n;i++) cout<<b[i];
cout<<endl;
//system("pause");
return 0;
}