给定两个正整数 N1<N2。把从 N1 到 N2 的每个数的各位数的立方相乘,再将结果的各位数求和,得到一批新的数字,再对这批新的数字重复上述操作,直到所有数字都是 1 位数为止。这时哪个数字最多,哪个就是“数字之王”。
例如 N1=1 和 N2=10 时,第一轮操作后得到 { 1, 8, 9, 10, 8, 9, 10, 8, 18, 0 };第二轮操作后得到 { 1, 8, 18, 0, 8, 18, 0, 8, 8, 0 };第三轮操作后得到 { 1, 8, 8, 0, 8, 8, 0, 8, 8, 0 }。所以数字之王就是 8。
本题就请你对任意给定的 N1<N2 求出对应的数字之王。
输入格式:
输入在第一行中给出两个正整数 0<N1<N2≤1000,其间以空格分隔。
输出格式:
首先在一行中输出数字之王的出现次数,随后第二行输出数字之王。例如对输入 1 10
就应该在两行中先后输出 6
和 8
。如果有并列的数字之王,则按递增序输出。数字间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
10 14
输出样例:
2
0 8
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
注:本题测试点有一点坑,尤其要注意输入是两个个位数的情况,否则会有两个测试点过不了。
AC代码如下:
#include <bits/stdc++.h>
using namespace std;
int digit_sum_pow(int number){//各位数的立方相乘,再将结果的各位数求和
int temp=number;
int sum=0;
int count_digit=0;
int tmp;
if(number==0) return 0;
do{
count_digit++;
temp/=10;
}while(temp);
if(count_digit==1){
tmp=number*number*number;
do{
sum+=tmp%10;
tmp/=10;
}while(tmp);
return sum;
}else if(count_digit==2){
int a=number%10;
int b=number/10;
tmp=a*a*a*b*b*b;
do{
sum+=(tmp%10);
tmp/=10;
}while(tmp);
return sum;
}else if(count_digit==3){
int a=number%10;
int b=(number/10)%10;
int c=number/100;
tmp=a*a*a*b*b*b*c*c*c;
do{
sum+=(tmp%10);
tmp/=10;
}while(tmp);
return sum;
}else if(count_digit==4){
return 0;//因为是1000,根据各位数立方相乘,结果为0
}
}
int main(){
int N1,N2;
cin>>N1>>N2;
int diff=N2-N1+2;
int count[11]={0};//数字之王出现次数
int i,j=0,k=0;
int number_oper[1001]={0};
int flag=0;//flag为1表示所有数字都为1位数
int max=-1;
//int index;
for(i=N1;i<=N2;i++){
number_oper[j]=i;//这里要注意是i,因为要考虑输入的两个数字都是个位数的情况,而不是digit_sum_pow(i);
j++;
}
while(!flag){
for(k=0;k<j;k++){
if(!(number_oper[k]>=0&&number_oper[k]<=9)){
break;
}
}
if(k==j) flag=1;//用于跳出循环
else{
for(k=0;k<j;k++){
number_oper[k]=digit_sum_pow(number_oper[k]);//进行新轮次的操作替换原来的数字
}
}
}
for(i=0;i<j;i++){
count[number_oper[i]]++;
}
for(i=0;i<=9;i++){
if(count[i]>max){
max=count[i];
//index=i;
}
}
cout<<max<<endl;
int cnt=0;
for(i=0;i<=9;i++){
if(max==count[i]&&!cnt){
cout<<i;
cnt++;
}
else if(max==count[i]&&cnt){
cout<<" "<<i;
cnt++;
}
}
return 0;
}