zoukankan      html  css  js  c++  java
  • uva 11121 Base 2

    数学题,给定一个十进制数转化为-2进制。这个问题可以扩展为转化为任意的负进制,先说-2进制

    算法:n mod -2 余数可能为-1,0,1,但是不能出现-1,只能有0,1所以将-1变为1,并且商要加1。然后依此迭代直到商为0为止。

    为什么余数要变为1而且能变为1呢,变了之后要怎么做呢?我找了很多博客都没有说原理,只是简单一句话,可能大家都觉得很简单吧,但是我还是想了一段时间才想出来的,所以就写一下原理

    我们来看一个10进制转2进制,例子1024

    第0次迭代,1024/2=512,1024%2=0 , 试一下把512++变为513,那么逆回去就是1026,多了2,其实就是2^1

    第1次迭代,512/2=256,512%2=0,试一下把256++变为257,那么逆回去,就是1028,多了4,其实就是2^2

    说到这里应该很清晰了,在第i次迭代后商+1,其实相当于原来的数增加了2^(i+1),这个有什么用呢

    n = b0 + b1(-2) + b2(-2)2 + b3(-2)3 + ...

    当n为正数的时候,第i次迭代的时候余数为-1的话,那么i一定是奇数(因为余数为正为负只和n的正负有关,而n的正负在除-2的过程中是交替变化的,很容易可以知道当i为奇数的时候,n是负数或0,余数是-1或0)那么对应的位置就应该是 -1*(-2)^i=2^i  ,如果变为1,则是1*(-2)^i=-2^i ,所以变为1后相当于减少了2*2^i=2^(i+1),减少了的要加回来啊,怎么加,就在第i次迭代后的商+1,上面说了,第i次迭代后商+1,相当于逆回去加了2^(i+1),所以以这个商继续迭代下去,最后得到的-2进制数就会等于原来的n

    同理,当n为负数的时候,也是一样的分析,就不写了。

    然后看代码

    #include <cstdio>
    #include <cstring>
    #define N 110
    int a[N];
    int n;
    int main()
    {
        int t,T;
        scanf("%d",&T);
        for(int t=1; t<=T; t++)
        {
            scanf("%d",&n);
            int c=-1; a[0]=0;
            while(n)
            {
                a[++c]=n%(-2);
                n=n/(-2);
                if(a[c]==-1)
                { a[c]=1; n++; }
            }
            printf("Case #%d: ",t);
            while(c>0) printf("%d",a[c--]);
            printf("%d",a[0]);
            printf("\n");
        }
        return 0;
    }

    按照这个原理我们不难写出转化为任意负进制的代码,先简单文字描述

    当n为正数的时候转化为-m进制,同样是当i为奇数的时候,会产生负的余数(或者0)-p,对应的位为(-p)*(-m)^i=p*m^i , 要把-p改为m-p , 那么对应的为就变为了(m-p)*(-m)^i=-(m-p)*m^i , 那么相当于原来减少了m*m^i=m^(i+1) , 减少的要补回来,就是在商那里+1,那么逆回去相当于增加了m^(i+1),刚好不回来,那么转化后的-m进制才是n

    同理n为负数的时候也是这么分析的

    核心代码

    //核心代码
    
     scanf("%d",&n);
     int c=-1; a[0]=0;
     while(n)
     {
         a[++c]=n%(-m);  //m就是m进制,-m就是负进制
         n=n/(-m);
         if(a[c]<0)
         { a[c]=m+a[c]; n++; }
     }
     printf("Case #%d: ",t);
     while(c>0) printf("%d",a[c--]);
     printf("%d",a[0]);
     printf("\n");
  • 相关阅读:
    获取进程编号
    通过队列完成进程之间的通信
    多进程的使用
    多任务的介绍
    nginx 的正向代理 和 反向代理
    nginx 学习 不断更新
    git 随笔(随时更新)
    mysql 主从复制
    指着他活着呢
    nginx正向代理 (带着请求头)
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2828420.html
Copyright © 2011-2022 走看看