2011年11月26日 星期六

整數分割

Every positive integer N can be written in at least one way
as a sum of terms of the form (2a)(3b) where no term in the
sum exactly divides any other term in the sum. For example:
1 = (20)(30)
7 = (22)(30) + (20)(31)
31 = (24)(30) + (20)(32) + (21)(31) = (22) + (33)
Note from the example of 31 that the representation is not unique.
Write a program which takes as input a positive integer N
and outputs a representation of N as a sum of terms of the
form (2a)(3b).

Example execution:
Please input a positive integer < 2^31-1: 123456789
The decomposition of 123456789 is [0,16] [2,15] [3,13] [4,12] [7,8]
[9,6] [10,5] [15,2]

Hints:
- For a positive integer n, you can write it as n = (2^k) * m, where m is an odd
integer and k >= 0.
- Now you can subtract the largest 3's power out of m, i.e., m = (3^L) + m'
and m' >= 3^L. Note that m' is even, let m' = 2k' * m'', where k' >= 1.
- Now you have n = 2^k (3^L + m') = 2^k 3^L + 2^k m' = 2k 3^L + 2^(k+k') * m’’ and
you are sure that 2^(k+k’) *  3^L'' does not divides 2^k 3^L since k' >= 1.
- You should output [k, L] and run the above steps for n = 2k m' again


#Code
#include <stdio.h>

int main(void)
{
    int n, tmp, tmp2, m, k, K, L;

    while (scanf("%d", &n) == 1)
    {
        K = 0;
        while (n >= 1)
        {
            tmp = 1;
            k = 1;
            while (n%tmp != 0 || (m = n/tmp) % 2 == 0)
            {
                tmp *= 2;
                k++;
            }
            k--;

            tmp = 1;
            L = 0;
            while (tmp <= m)
            {
                tmp2 = tmp;
                tmp *= 3;
                L++;
            }
            L--;
            K += k;
            printf("[%d, %d]", K, L);
            n = m - tmp2;
        }
        printf("\n");
    }

    return 0;
}

沒有留言:

張貼留言