题目描述:
小b有一个数n,现在她想把n的每一位重排列,使得得到的结果为2的幂次。
请问小b能得到2的幂次吗?
注意重排列后不允许有前导0。
样例解释:46重排列成64,为2^6。
收起
输入
输入一个数N,其中1≤N≤10^9
输出
满足条件,输出“true”; 不满足,则输出“false”。
输入样例
46
输出样例
true
题解:
如果先处理得到 n 的每一位,之后用全排列的方式枚举所有排列,再判断是否为2的幂,那么复杂度为指数的。反过来,如果我们先求出所有 2 的幂,再对每一个数用上面相同的方法,枚举对应的全排列,复杂度也是指数的。那么该如何快速判断呢?
我们考虑如果能够自定义一种方法 F ,让 F(n)=k ,同时 F(2x)=k ,假如 n 与 2k 包括的字符完全相同时。
这里我们可以利用有序化的思想,对字符进行排序,如果两个字符串包括的字符完全相同,那么经过排序后得到的两个字符是完全相同的。例如:
bbca,bcab,cabb 虽然都不相同,但经过字符排序后,得到的都是 abbc 。
这样做的复杂度是对数字排序的复杂度,假设数字的长度为 L ,那么复杂度为 O(LlogL) 。
#include<bits/stdc++.h>
using namespace std;
int a[20];
int main()
{
ios::sync_with_stdio(false);
int n,tip=0;
cin>>n;
while(n)
{
a[tip++]=n%10;
n/=10;
}
sort(a,a+tip);
do
{
if(a[0]==0)
continue;
int t=0;
for(int i=0;i<tip;i++)
t=t*10+a[i];
while(t%2==0)
{
t/=2;
}
if(t==1)
{
cout<<"true";
return 0;
}
}while(next_permutation(a,a+tip));
cout<<"false";
return 0;
}