问题 F: 幂十全数
题目描述
如果一个数包含了0~9这十个数字,就称为十全数。给定N,找一个最小的正整数M,使N^M为十全数。
(N^M表示连续M个N连乘,如2^3=2*2*2)
输入
输入文件仅一行,即N(0<=N<=100)。
输出
输出文件仅一行,若无解,输出-1,否则输出M。
样例
题目要求找到一个最小的正整数 𝑀M,使得 𝑁𝑀NM 的结果包含数字 0 到 9 的所有数字至少一次。具体来说:
- 给定一个整数 𝑁N(范围为 0 到 100)。
- 计算 𝑁𝑀NM,其中 𝑀M 是正整数。
- 要求 𝑁𝑀NM 的结果必须包含数字 0 到 9 的每一个数字至少一次。
- 如果存在这样的 𝑀M,则输出这个 𝑀M,否则输出 -1。
例如,对于输入 𝑁=4N=4,最小的 𝑀M 是 34,因为 434434 的结果包含数字 0 到 9 的所有数字。
听上去好做但是挺难的
我们可以先特判一下:0、1、可以整除10的。
这样完成了重要的一步
然后
1、存储(用set并检查是否包含了0到9所有的数字)。具体操作:函数返回一个布尔值,检查集合的大小是否为 10(确保包含了0到9的所有数字),并且逐个检查是否每个数字都被包含在集合中。
2、以字符串形式的做数字乘法。具体操作:从字符串的最低位开始模拟乘法运算,将每位的结果保存在 r(就是一个变量) 中,最后处理进位。最后,去除结果字符串开头多余的零并返回。
3、寻找最小的正整数M使得N^M为十全数。具体操作:使用一个循环从M=1开始计算N^M,每次计算后调用 f
函数检查是否包含了所有数字。如果找到了满足条件的 M则返回该 M;如果循环完毕仍未找到,则返回 -1。(其实不需要写了没写一样)
4、主函数:从标准输入读取整数N,然后根据一些简单的条件判断(如N=0或者末尾是0),直接输出 -1。否则调用 find
函数寻找满足条件的M并输出结果。
最后是代码时间:
上一个88%(时间超限的代码)(看完自己肯定会改!(ง •_•)ง)
#include<bits/stdc++.h>
using namespace std;
// 判断一个数是否包含0到9所有的数字
bool f(const std::string&num_str) {
std::set<char>digits(num_str.begin(),num_str.end());
return digits.size()==10&&digits.count('0')&&digits.count('1')&&digits.count('2')&&digits.count('3')&&digits.count('4')&&digits.count('5')&&digits.count('6')&&digits.count('7')&&digits.count('8')&&digits.count('9');
}
// 字符串乘法
std::string m(const std::string& num1, int num2) {
std::string r(num1.size()+ 10, '0');
int carry=0,pos=r.size()-1;
for (int i=num1.size()-1;i>=0;--i) {
int temp=(num1[i]-'0')*num2+carry;
r[pos--]=temp%10+'0';
carry=temp/10;
}
while (carry) {
r[pos--]=carry%10+'0';
carry/=10;
}
size_t startpos=r.find_first_not_of('0');
if (std::string::npos!=startpos) {
return r.substr(startpos);
}
return "0";
}
// 寻找最小的正整数M使得N^M为十全数
int find(int N) {
if (N==0) {
return -1;
}
std::string current_value=std::to_string(N);
for (int M=1;M<=100000;++M) {
if (f(current_value)) {
return M;
}
current_value=m(current_value, N);
}
return -1;
}
int main() {
int N;
std::cin>>N;
int result=find(N);
if(N==0||N==1||N%10==0)
cout<<-1;
else
std::cout<<result<< std::endl;
return 0;
}