Finding gcd of permutations of a Number

房东的猫 提交于 2019-12-23 05:21:17

问题


Here is the link to the problem:

http://www.spoj.com/problems/GCD/

Consider the decimal representation of a natural number N. Find the greatest common divisor (GCD) of all numbers that can be obtained by permuting the digits in the given number. Leading zeroes are allowed.

I worked on the following approach : https://math.stackexchange.com/a/22453

First, if all the digits are the same, there is only one number and that is the GCD. As was pointed out before, if 3 or 9 is a factor of one permutation it will be a factor of them all. Otherwise, imagine swapping just the ones and tens digit when they are different. The GCD of these two has to divide 100a+10b+c−100a+10c+b=9(b−c) where b and c are single digits. For the GCD of all the numbers to have a factor 2, all the digits must be even. For the GCD to have a factor 4, all the digits must be 0, 4, or 8 and for 8 they must be 0 or 8. Similarly for 5 and 7. Finally, the GCD will be 27 if all the digits are 0,3,6, or 9 and 27 divides one permutation and 81 if all the digits are 0 or 9 and 81 divides one permutation. Can you prove the last assertion?

My solution: http://ideone.com/VMUb6w

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<string>



using namespace std;

int rem(string str, int a){
    if (str.empty())
    {
        return 0;
    }
    int temp = (str[str.length() - 1] - '0') % a;
    int temp2 = 10 % a;
    str.erase(str.length() - 1);
    int temp3 = (rem(str, a)*temp2) % a;
    return (temp3 + temp) % a;
}


int gcdf(int a, int b)
{
    return b ? gcdf(b, a%b) : a;
}


int main(){
    string str;
    while (cin >> str)
    {

    size_t l = str.length();
    vector<int> digit;
    int sum = 0;
    int frequency[9];
    for (int i = 0; i<9; i++)
        frequency[i] = 0;
    int zero_sum = 0;
    for (size_t i = 0; i < l; i++)
    {
        if (str.at(i) != '0')
        {
            frequency[str.at(i) - '1']++;
            sum += str.at(i) - '0';
        }
        else
        {
            zero_sum++;
        }
    }

    for (size_t i = 0; i < 9; i++)
    {
        if (frequency[i])
        {
            digit.push_back(i + 1);
        }
    }
    int gcds = 0, gcd = 1;
    for (size_t i = 0; i < digit.size(); i++)
    {
        gcds = gcdf(digit[i], gcds);
    }
    if (gcdf(3, gcds) == 1)
    {
        gcd *= gcds;
    }
    if (gcds == 6)
    {
        gcd *= 2;
    }
    if ((rem(str, 81) == 0) && (gcdf(gcds, 3) == 3))
    {
        gcd *= 81;
    }
    else
    {
        if ((rem(str, 27) == 0) && (gcdf(gcds, 3) == 3))
        {
            gcd *= 27;
        }
        else
        {
            if (sum % 9 == 0)
            {
                gcd *= 9;
            }
            else
            {
                if (sum % 3 == 0)
                {
                    gcd *= 3;
                }
            }
        }
    }
    if((digit.size()==1)&&(zero_sum==0))
            cout<<str;
    else            
         cout << gcd << endl;


}
return 0;
}

But it is giving WA. I cannot seem to find any edge case on where it might be wrong.

Please tell me where am i wrong. Thanks :)


回答1:


First, if all the digits are the same, there is only one number and that is the GCD.

You don't handle this (first) case

So with your code all of 11, 111, 44 gives wrong answer.

[..] 81 if all the digits are 0 or 9 and 81 divides one permutation.

It seems that your test is wrong for that:

if ((rem(str, 81) == 0) && (gcdf(gcds, 3) == 3))

Did you mean:

if ((rem(str, 81) == 0) && (gcdf(gcds, 9) == 9))

And so

You have for permutation of 3699 inconsistent results:

27 for 3699, 3996, 6939, 6993, 9369, 9693, 9936
81 for 3969, 6399, 9396, 9639, 9963.

My implementation to check (for int number) is:

int my_gcd(std::string str)
{
    std::sort(str.begin(), str.end());
    std::string first = str;
    int gcd = atoi(first.c_str());

    while (std::next_permutation(str.begin(), str.end())) {
        gcd = gcdf(atoi(str.c_str()), gcd);
    }
    return gcd;
}


来源:https://stackoverflow.com/questions/25698691/finding-gcd-of-permutations-of-a-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!