zoukankan      html  css  js  c++  java
  • UVa 11121

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2062


    题目大意就是给你一个-1000,000,000到1000,000,000的数转化成-2进制。

    看到-2就想到了2进制,原先想两位两位地考虑,然后看成2进制的,接下来求一下方程的正数解就行了,然后将那些数全都转化成0和1,后来又发现。。每项之间差了4倍,顿时就不行了。接着想着是不是能将 (-2)^k 和 2^k 联系起来,那问题就简单了。

    后来看到了一个式子,顿时有了点灵感 : (4)^3 = (-4)^4 + (4 - 1) * (-4)^3

    想了想后总结出来了一个结论

    ①当k是奇数的时候, 2^k = (-2)^(k+1) + (-2)^k;

    ②当k是偶数的时候, 2^k = (-2)^k;

    推导的过程中也有遇到一些问题,一直想把偶数和奇数的情况联系在一起,但是感觉做不到,而且可能会出现负数,出现负数就不好处理了。

    有了以上的结论,差不多就可以开始动手了。但是突然想到,负数的话,算出来的东西就会出问题了,想了想,负数和整数应该有类似的结论,经过尝试后推倒出这样的结论。

    ①当k是奇数的时候, -2^k = (-2)^k;

    ②当k是偶数的时候, -2^k = (-2)^(k + 1) + (-2)^(k + 1);

    接下来就开始写代码了,但是测试了一下,一些数转化后出现了让人觉得很囧的大于1的数字,突然想到还要经行进位处理。想了想挺容易推导的,但是注意最好不要出现负数的情况,不然就不好处理了。

    2 * (-2)^k = (-2)^(k + 1) + (-2)^(k + 2);

    于是进位的操作就ok了

    但程序到这里还是有bug的,试了一下1000,000,000,结果发现后面的结果还是很正常,前面多出了个4,顿时觉得很纳闷,然后认真地调试了下,发现出现了一个4和2的循环,高位的系数是2,低位的系数是4,突然反应过来,完全是可以抵消掉的,但是没有抵消就出现了4和2的循环。

    ans[k+1] = 2ans[k];

    每次进位前先进行抵消操作,然后开始进位,接下来程序终于没了bug了,顺利AC了。


    其实这个还是可以推广的,按照刚才的公式,我们假设现在是(-b)进制,有以下的结论

    n为正数

    ①当k为奇数的时候,b^k = (-b)^(k + 1) + (b - 1) * (-b)^k

    ②当k为偶数的时候,b^k = (-b)^k;

    n为负数

    ①当k为奇数的时候,- b^k = (-b)^k;

    ②当k为偶数的时候,- b^k = (-b)^(k + 1) + (b - 1) * (-b) ^ k;

    进位:

    ①当k为偶数的时候,b * (-b)^k = (-b)^(k + 1);

    ②当k为奇数的时候,b * (-b)^k = - b^(k + 1) = - (-b)^(k + 1) = - b^(k + 1) = (-b)^(k + 2) + (b - 1) * (-b)^(k + 1);

    抵消

    ans[k+1] = b * ans[k];

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const int MAXN = 64 + 5;
    
    int n, flag;
    int ans[MAXN];
    
    int main()
    {
        int tCase;
    
        while(scanf("%d", &tCase) != EOF)
            for(int T = 1; T <= tCase; ++ T)
            {
                flag = 1;
                scanf("%d", &n);
                memset(ans, 0, sizeof(ans));
    
                if(n < 0)
                {
                    flag = 0;
                    n = ~n + 1;
                }
    
                //转化
                for(int i = 0; i < 31; ++ i)
                    if(n & (1 << i))
                    {
                        ++ans[i];
    
                        if((i & 1) == flag)
                            ++ans[i + 1];
                    }
    
                //进位
                for(int i = 0; i < MAXN - 1; ++ i)
                {
                    //抵消
                    if(ans[i] >= ((ans[i + 1] >> 1) << 1))
                    {
                        ans[i] -= ((ans[i + 1] >> 1) << 1);
                        ans[i + 1] -= (ans[i + 1] >> 1);
                    }
    
                    while(ans[i] > 1)
                    {
                        ++ans[i + 1];
                        ++ans[i + 2];
                        ans[i] -= 2;
                    }
                }
    
                printf("Case #%d: ", T);
    
                for(int i = MAXN - 1; i > 0; -- i)
                    if(ans[i] != 0)
                    {
                        for(int j = i; j > 0; --j)
                            putchar(ans[j] + '0');
    
                        break;
                    }
    
                putchar(ans[0] + '0');
                putchar('
    ');
            }
    
        return 0;
    }
    View Code


  • 相关阅读:
    AcWing 1135. 新年好 图论 枚举
    uva 10196 将军 模拟
    LeetCode 120. 三角形最小路径和 dp
    LeetCode 350. 两个数组的交集 II 哈希
    LeetCode 174. 地下城游戏 dp
    LeetCode 面试题 16.11.. 跳水板 模拟
    LeetCode 112. 路径总和 递归 树的遍历
    AcWing 1129. 热浪 spfa
    Thymeleaf Javascript 取值
    Thymeleaf Javascript 取值
  • 原文地址:https://www.cnblogs.com/tank39/p/3911404.html
Copyright © 2011-2022 走看看