描述
自幂:对于一个正整数,每一次将该数替换为它每个位置上的数字的p次幂之和。
给你一个正整数x,和正整数幂p,如果这个数字最终会变成某个数字并且保持不变,那么就是快乐自幂数。
去需要你判断正整数x不断自幂后,能不能变成快乐自幂数。
输入
多组案例。一个正整数n,表示案例的数量。(n<=100)
每组案例由正整数x,和正整数p组成。(p<=10)
对于 33% 的样例有 x <=1e2。
对于 66% 的样例有 x <=1e10。
对于 100% 的样例有 x <= 1e100。
输出
针对每组案例,如果这个数字会变成快乐自幂数,输出yes,否则输出no,然后换行。
样例输入
3
100 2
7 2
666 10
样例输出
yes
yes
no
HINT
第一组案例,100->1->1->1…
第二组案例,7->49>97->130->10->1->1->1…
#include<iostream>
#include<map>
#include<algorithm>
#include<string>
using namespace std;
typedef unsigned long long int ll;
int main()
{
int n;
cin >> n;
while (n--)
{
string x;//x <= 1e100
ll sum = 0;
int p;
cin >> x >> p;
map<ll,int>mp;//记录数字出现次数
for (int i = 0; i < x.size(); i++)
{
ll num = 1;
for (int j = 0; j < p; j++)
{
num *= (x[i] - '0');
//运用char转int 将单个位置上的数字的p次幂用num记录
}
sum += num;//p次幂之和
}
if (sum == 1 || p == 1)
{
cout << "yes" << endl;
//如果出现1那么将会进入循环 开1次幂同理
}
else//进行模拟
{
mp[sum]++;
//记录一个数字出现次数 如果这个数字出现两次说明进入有限循环 不能变成快乐自幂数
ll last = sum;//将这一次的数字存储
while (true)//开始循环
{
ll sum1 = 0;//开始记录新的p次幂和
while (sum > 0)//进行与21-26行相同的内容
{
ll num1 = sum % 10;
ll num = 1;
for (int i = 0; i < p; i++)
{
num *= num1;
}
sum1 += num;
sum /= 10;
}
sum = sum1;//将这一次的数据记录
if (sum == 1 || sum == last)//同第28行
{
cout << "yes" << endl;
break;
}
if (mp[sum])//如果这个数字出现过了 那么同理36行
{
cout << "no" << endl;
break;
}
else
{
last = sum;//同理35-37行
mp[sum]++;
}
}
}
}
return 0;
}