题目描述
如果一个数是正整数,且其十进制符号中的所有数字都是 0 0 0 或 1 1 1,我们就称它为二进制型十进制数。例如, 1010111 1010111 1010111 是二进制型十进制数,而 10201 10201 10201 和 787788 787788 787788 不是。
给定一个数 n n n,问你是否可以将 n n n 表示为一些(不一定不同的)二进制型十进制数的乘积。
输入格式
一行包含一个整数 n ( 1 ≤ n ≤ 1 0 5 ) n(1 \leq n \leq 10^5) n(1≤n≤105)。
输出格式
如果
n
n
n 可以表示为二进制型十进制数的乘积,则输出 “YES”,否则输出 “NO”(都不带引号)。
(字符串 “yES”、"yes "和 "Yes "将被识别为正确的,“NO” 同理)。
样例输入1
121
样例输出1
YES
样例输入2
12421
样例输出2
NO
提交链接
提示
样例解释 1 1 1:
121 = 11 × 11 121=11×11 121=11×11
解析
观察 n n n 的范围,最大也只是 100000 100000 100000,我们可以预处理出来 1 ∼ 100000 1 \sim 100000 1∼100000 范围内的所有的二进制型的十进制数,进行保存。
对于这些二进制型的十进制数,可以进行搜索,看能组成那些数。能组成的这些数,一定可以拆分为若干二进制型的十进制数。进行标记。
输入的
n
n
n ,根据标记,输出
Y
E
S
/
N
O
YES/NO
YES/NO。
搜索的整体思路:
结束条件:所有的二进制型的十进制数已经用完(下标超出范围);组成的数超出 10000 10000 10000 无意义。
初始参数 ( 0 , 1 ) (0,1) (0,1):从下标为 0 0 0 的数开始用,初始的乘积为 1 1 1。
递归:当前这个数用若干次的基础上,考虑下一个数用的次数。
参考代码
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 9 , mod = 1e9 + 7;
typedef long long ll;
int t , n;
bool vis[maxn];
vector<int>v;
bool check(int x) //检查x是否为二进制型的十进制数
{
while(x)
{
if(x % 10 > 1)
return false;
x /= 10;
}
return true;
}
//当前选择下标为id的数 已经选取的符合条件的数的乘积为fac
void dfs(int id , ll fac)
{
if(id >= v.size())
return;
if(fac > 100000)
return;
vis[fac] = true;
ll ans = 1;
for(int i = 1; ; i++)
{
if(ans * fac > 100000)
break;
dfs(id + 1 , fac * ans);
ans *= v[id];
}
}
int main()
{
//打表 预处理
for(int i = 2; i <= 200000; i++)
{
if(check(i))
v.push_back(i);
}
dfs(0 , 1);
cin >> n;
if(vis[n])
cout << "YEs" << endl;
else
cout << "nO" << endl;
return 0;
}