poj1023

题目描述:给一个长度为k的二进制符号序列,每一位都有两种状态,正的(用p表示)和负的(用n表示),给一个n,现在要求有没有满足条件的二进制数在按照给定的序列转化成10进制后等于n的。
example:例如给定序列长度为4,二进制符号序列是ppnn,给定n为10,则二进制数为1110,因为1*2^3+1*2^2-1*2^1-0*2^0==10
输入格式:第一行一个整数t,表示有t组数据,每组数据三行,第一行是一个整数k,表示二进制符号序列的长度,第二行是一个长度为k的字符串,由p或者n组成,第三行是一个整数n。
输出格式: Impossible或者一个二进制数,如果符合条件的k位二进制数没有,则输出Impossible,否则输出满足条件的二进制数。
解题思路: 这道题我一开始看了之后完全没有头绪。。。。然后我随便试了试自己的一个想法,也不知道对不对。我的想法:

  • 首先可以肯定的是,如果n是偶数,那么它的最低位一定是0,不管它的最低位是n还是p;如果n是奇数,那么最低位是1,那么,问题来了,问题是什么呢?等下看第三条。
  • 现在可以肯定的是如果n是偶数,那么它的最低位一定是0,那么我们就可以考虑n/2的情况了,是不是把n右移一位。试想,如果,每次把n右移一位,是不是都可以确定二进制数的一个binary位。
  • 那么现在来考虑如果n是奇数的情况。好吧,我也不知道为什么,我就是鬼使神差的这样处理了:如果n是奇数那么我就把n右移一位然后加一。

当时并没有想这是为什么,然后答案竟然对了。。然后是处理一些小细节,例如n是9223372036854775807的时候,必须先把n右移再加一。。还有就是n的范围需要是long long。。。
然后现在想想,发现好像就是,如果n是奇数时k-1位是正的,那么没问题,这个位一定是1,也不需要改n,如果这个位是负的,那么跟正的相比,差了两个当前k-1位大小的值(2^k),然后我们把n除以二再加一就相当于把这个值修正了。。
具体的看代码(这次代码写的好丑TnT):
PS:由于看ICPC的WorldFinal去了,没有第一时间写题解@_@!!!
继续看live去惹@_@~~~

#include <cstdio>
#define MAXN 66

int main(int argc, char const *argv[])
{
    int t;
    for(scanf("%d", &t); t--;){
        int k; 
        long long n;
        char sign[MAXN];
        scanf("%d\n", &k);
        for(int i=0; i<k; ++i){
            sign[k-i-1]=getchar();
        }
        scanf("%lld", &n);
        bool bit[MAXN] = {false};
        for(int i=0; i<k; ++i){
            if(n&1) { 
                bit[i] = true;
                if(sign[i]=='p'){
                    n>>=1;
                } else {
                    n=(n>>1)+1;
                }
            } else {
                bit[i] = false;
                n>>=1;
            }
        }
        if(n!=0) { 
            printf("Impossible\n"); 
            continue;
        }
        for(int i=k; i>0; --i){
            if(bit[i-1]){
                printf("1");
            } else {
                printf("0");
            }
        }
        printf("\n");
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值