51nod2512 重排列得到2的幂 做题感悟

博客分享了作者在解决一道算法问题时的心路历程,探讨了如何将一个数的位重排列成2的幂次。作者从初始的暴力方法到优化思路,最终实现O(1)的时间复杂度解决方案,虽然中间经历了错误和困扰,但通过不断尝试和思考找到了正确答案。文章以轻松幽默的方式展现了编程解题过程中的挑战和乐趣。

今天做了一道题,逝的,花费了114514%57257根头发,花费了生命中的不知道多长时间解决了一道题

老套路,先做题,再优化,这一优化,就出逝情了

题目:


b 有一个数 n ,现在她想把 n 的每一位重排列,使得得到的结果为 2 的幂次。

请问小 b 能得到 2 的幂次吗?

注意重排列后不允许有前导 0

样例解释: 46 重排列成 64 ,为 2^6

输入

输入一个数 N ,其中 1≤N≤10^9

输出

满足条件,输出 "true"

不满足,则输出 "false"

输入样例

46

输出样例

true


最近做题被时间复杂度折磨的遍体鳞伤,一看到这个题,1<=N<=10^9,脑瓜子就嗡嗡响,O(n^2)准保不行,O(nlog(n))可能够呛,O(n)才行,或者是O(log(n))、O(1)……(这里的n均为输入的N的长度)

我想了想,在牺牲了N/1e10根头发之后,第n反应就是:

把2的幂和输入进来的N的位数都排序了,(比如N=264836,排序之后N=234668),然后一个一个比就行了

后来又升级了以下这个想法:

把2的幂排序过的数打表,把N逐位排序再比对就行了

打表时,用下面这个程序跑了一下,然后……

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long n=2;
    while(n<=1000000000){//n<=10^9
        cout << n << ",";
        n*=2;
    }
    return 0;
}

输出逝……

2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,

数了一下(对程序做了一点微小的改动,让电脑代劳),一共有……29个

29个……不多嘛……不多……不……等等,这么打表几乎没有降运行时间啊

那打表的意义何在???

蓑以,我就又思索了那么亿会,又牺牲了0x000000根头发后,脑中忽然蹦出了一个想法:

用map把N每一位的数字录入进去,再和2的幂一个一个比对,就可以做到O(1)解题了

我猛然想起,除了空间换时间,还可以键盘换时间

于是,就开干了

……

算了,先亮代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    long long n,a;
    map<int,int> mp;
    cin >> n;
    a=n;
    while(n){
        mp[n%10]++;
        n/=10;
    }
    if (a==2||a==4||a==8||a==16||a==61||a==32||a==23||a==46||a==64) cout << "true";//2,4,8,16,32,64
    else if(mp[0]==0 && mp[1]==1 && mp[2]==2 && mp[3]==0 && mp[4]==0 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==1 && mp[9]==0) cout << "true";//128
    else if(mp[0]==0 && mp[1]==0 && mp[2]==1 && mp[3]==0 && mp[4]==0 && mp[5]==1 && mp[6]==1 && mp[7]==0 && mp[8]==0 && mp[9]==0) cout << "true";//256
    else if((mp[0]==0 && mp[1]==1 && mp[2]==1 && mp[3]==0 && mp[4]==0 && mp[5]==1 && mp[6]==0 && mp[7]==0 && mp[8]==0 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==1 && mp[3]==0 && mp[4]==1 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==0 && mp[9]==0)||(mp[0]==1 && mp[1]==0 && mp[2]==1 && mp[3]==0 && mp[4]==1 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==1 && mp[9]==0)||(mp[0]==1 && mp[1]==0 && mp[2]==0 && mp[3]==0 && mp[4]==1 && mp[5]==0 && mp[6]==1 && mp[7]==0 && mp[8]==0 && mp[9]==1)) cout << "true";//512,1024,2048,4096
    else if((mp[0]==0 && mp[1]==1 && mp[2]==1 && mp[3]==0 && mp[4]==0 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==1 && mp[9]==1)||(mp[0]==0 && mp[1]==1 && mp[2]==0 && mp[3]==1 && mp[4]==1 && mp[5]==0 && mp[6]==1 && mp[7]==0 && mp[8]==1 && mp[9]==0)||(mp[0]==0 && mp[1]==0 && mp[2]==1 && mp[3]==1 && mp[4]==0 && mp[5]==0 && mp[6]==1 && mp[7]==1 && mp[8]==1 && mp[9]==0)||(mp[0]==0 && mp[1]==0 && mp[2]==0 && mp[3]==1 && mp[4]==0 && mp[5]==2 && mp[6]==2 && mp[7]==0 && mp[8]==0 && mp[9]==0)) cout << "true";//8192,16384,32768,65536
    else if((mp[0]==1 && mp[1]==2 && mp[2]==1 && mp[3]==1 && mp[4]==0 && mp[5]==0 && mp[6]==0 && mp[7]==1 && mp[8]==0 && mp[9]==0)||(mp[0]==0 && mp[1]==1 && mp[2]==2 && mp[3]==0 && mp[4]==2 && mp[5]==0 && mp[6]==1 && mp[7]==0 && mp[8]==0 && mp[9]==0)||(mp[0]==0 && mp[1]==0 && mp[2]==2 && mp[3]==0 && mp[4]==1 && mp[5]==1 && mp[6]==0 && mp[7]==0 && mp[8]==2 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==0 && mp[3]==0 && mp[4]==1 && mp[5]==1 && mp[6]==1 && mp[7]==1 && mp[8]==1 && mp[9]==0)) cout << "true";//131072,262144,524288,1048576
    else if((mp[0]==0 && mp[1]==2 && mp[2]==1 && mp[3]==0 && mp[4]==0 && mp[5]==0 && mp[6]==2 && mp[7]==3 && mp[8]==0 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==0 && mp[3]==1 && mp[4]==3 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==0 && mp[9]==1)||(mp[0]==1 && mp[1]==0 && mp[2]==0 && mp[3]==1 && mp[4]==0 && mp[5]==0 && mp[6]==1 && mp[7]==0 && mp[8]==4 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==2 && mp[3]==0 && mp[4]==0 && mp[5]==1 && mp[6]==0 && mp[7]==1 && mp[8]==0 && mp[9]==1)) cout << "true";//16777216,2097152,4194304,838860
    else if((mp[0]==0 && mp[1]==0 && mp[2]==1 && mp[3]==3 && mp[4]==2 && mp[5]==2 && mp[6]==0 && mp[7]==0 && mp[8]==0 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==0 && mp[3]==0 && mp[4]==1 && mp[5]==0 && mp[6]==2 && mp[7]==1 && mp[8]==2 && mp[9]==0)||(mp[0]==0 && mp[1]==2 && mp[2]==2 && mp[3]==1 && mp[4]==1 && mp[5]==0 && mp[6]==0 && mp[7]==2 && mp[8]==1 && mp[9]==0)||(mp[0]==0 && mp[1]==0 && mp[2]==1 && mp[3]==1 && mp[4]==2 && mp[5]==2 && mp[6]==2 && mp[7]==0 && mp[8]==1 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==1 && mp[3]==1 && mp[4]==0 && mp[5]==1 && mp[6]==1 && mp[7]==1 && mp[8]==1 && mp[9]==1)) cout << "true";//33554432,67108864,134217728,268435456,536870912
    else cout << "false";
    return 0;
}
//由于使用了键盘换时间的方法,敲代码的时候心神不宁,格式不太规整(本人就是强迫症,现在已经要疯掉了)

然后我就信心满满地提交了上去

然后就Wrong Answer了

然后发现只有一个测试项错了

然后就像维修那个世界上第一台计算机一样找bug

然后就没找出来

然后就随便试了一下

然后发现答案是true

然后就又是猛一激灵

发现2^0竟然也被这个缺德的出题人算进去了

所以

看客们

你们知道怎么改了嘛

算了,我还是把最后AC的代码放出来吧

#include <bits/stdc++.h>
using namespace std;

int main() {
    long long n,a;
    map<int,int> mp;
    cin >> n;
    a=n;
    while(n){
        mp[n%10]++;
        n/=10;
    }
    if (a==1||a==2||a==4||a==8||a==16||a==61||a==32||a==23||a==46||a==64) cout << "true";//1,2,4,8,16,32,64
    else if(mp[0]==0 && mp[1]==1 && mp[2]==2 && mp[3]==0 && mp[4]==0 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==1 && mp[9]==0) cout << "true";//128
    else if(mp[0]==0 && mp[1]==0 && mp[2]==1 && mp[3]==0 && mp[4]==0 && mp[5]==1 && mp[6]==1 && mp[7]==0 && mp[8]==0 && mp[9]==0) cout << "true";//256
    else if((mp[0]==0 && mp[1]==1 && mp[2]==1 && mp[3]==0 && mp[4]==0 && mp[5]==1 && mp[6]==0 && mp[7]==0 && mp[8]==0 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==1 && mp[3]==0 && mp[4]==1 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==0 && mp[9]==0)||(mp[0]==1 && mp[1]==0 && mp[2]==1 && mp[3]==0 && mp[4]==1 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==1 && mp[9]==0)||(mp[0]==1 && mp[1]==0 && mp[2]==0 && mp[3]==0 && mp[4]==1 && mp[5]==0 && mp[6]==1 && mp[7]==0 && mp[8]==0 && mp[9]==1)) cout << "true";//512,1024,2048,4096
    else if((mp[0]==0 && mp[1]==1 && mp[2]==1 && mp[3]==0 && mp[4]==0 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==1 && mp[9]==1)||(mp[0]==0 && mp[1]==1 && mp[2]==0 && mp[3]==1 && mp[4]==1 && mp[5]==0 && mp[6]==1 && mp[7]==0 && mp[8]==1 && mp[9]==0)||(mp[0]==0 && mp[1]==0 && mp[2]==1 && mp[3]==1 && mp[4]==0 && mp[5]==0 && mp[6]==1 && mp[7]==1 && mp[8]==1 && mp[9]==0)||(mp[0]==0 && mp[1]==0 && mp[2]==0 && mp[3]==1 && mp[4]==0 && mp[5]==2 && mp[6]==2 && mp[7]==0 && mp[8]==0 && mp[9]==0)) cout << "true";//8192,16384,32768,65536
    else if((mp[0]==1 && mp[1]==2 && mp[2]==1 && mp[3]==1 && mp[4]==0 && mp[5]==0 && mp[6]==0 && mp[7]==1 && mp[8]==0 && mp[9]==0)||(mp[0]==0 && mp[1]==1 && mp[2]==2 && mp[3]==0 && mp[4]==2 && mp[5]==0 && mp[6]==1 && mp[7]==0 && mp[8]==0 && mp[9]==0)||(mp[0]==0 && mp[1]==0 && mp[2]==2 && mp[3]==0 && mp[4]==1 && mp[5]==1 && mp[6]==0 && mp[7]==0 && mp[8]==2 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==0 && mp[3]==0 && mp[4]==1 && mp[5]==1 && mp[6]==1 && mp[7]==1 && mp[8]==1 && mp[9]==0)) cout << "true";//131072,262144,524288,1048576
    else if((mp[0]==0 && mp[1]==2 && mp[2]==1 && mp[3]==0 && mp[4]==0 && mp[5]==0 && mp[6]==2 && mp[7]==3 && mp[8]==0 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==0 && mp[3]==1 && mp[4]==3 && mp[5]==0 && mp[6]==0 && mp[7]==0 && mp[8]==0 && mp[9]==1)||(mp[0]==1 && mp[1]==0 && mp[2]==0 && mp[3]==1 && mp[4]==0 && mp[5]==0 && mp[6]==1 && mp[7]==0 && mp[8]==4 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==2 && mp[3]==0 && mp[4]==0 && mp[5]==1 && mp[6]==0 && mp[7]==1 && mp[8]==0 && mp[9]==1)) cout << "true";//16777216,2097152,4194304,838860
    else if((mp[0]==0 && mp[1]==0 && mp[2]==1 && mp[3]==3 && mp[4]==2 && mp[5]==2 && mp[6]==0 && mp[7]==0 && mp[8]==0 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==0 && mp[3]==0 && mp[4]==1 && mp[5]==0 && mp[6]==2 && mp[7]==1 && mp[8]==2 && mp[9]==0)||(mp[0]==0 && mp[1]==2 && mp[2]==2 && mp[3]==1 && mp[4]==1 && mp[5]==0 && mp[6]==0 && mp[7]==2 && mp[8]==1 && mp[9]==0)||(mp[0]==0 && mp[1]==0 && mp[2]==1 && mp[3]==1 && mp[4]==2 && mp[5]==2 && mp[6]==2 && mp[7]==0 && mp[8]==1 && mp[9]==0)||(mp[0]==1 && mp[1]==1 && mp[2]==1 && mp[3]==1 && mp[4]==0 && mp[5]==1 && mp[6]==1 && mp[7]==1 && mp[8]==1 && mp[9]==1)) cout << "true";//33554432,67108864,134217728,268435456,536870912
    else cout << "false";
    return 0;
}

(这是本人发的第一篇文章,不喜勿喷)

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值