Topcoder SRM 661 Div1 Easy: MissingLCM

題目大意

衆所周知,LCM指最小公倍數。
令A=LCM(1~m)
B=LCM(n+1~m)
求一個最小的m使得A=B。

題解

寫這道題的時候,毫不猶豫,先敲了一個暴力,反正就算不能AC也可以找找規律,驗證猜想。
結果發現,LCM增長得非常快,即使是n=48的小數據,也跑不出來。
於是怒而找規律,看了三組樣例,以爲輸出就是n*2,結果就被出題人嘲諷了。出題人在某組答案並非n*2的數據後面加了一句:似乎不滿足規律了。
於是我就順着這個思路思考了下去。
我感覺,貌似如果這個數可以被拆分成兩個數,也就是不是質數,就應該continue掉,然後找到最早的一個質數乘2輸出。
當然這是錯的,馬上就WA了。
於是我有加了一句判斷,就是拆分成的這兩個數不能相互整除,然後就AC了。
反正我也不知道這樣是不是對的,但是我知道的是:hack數據都是2n+1 ,答案都是2n2
就這樣AC了,感覺是水過的呀!!!
先貼一下我的代碼,再說正解。

class MissingLCM {
public:
    int getMin(int N) {
        for(int i=N;i>=1;i--){
            bool f=1;
            for(int j=floor(sqrt(i));j>1;j--){
                if(i%j==0&&i/j!=j&&i/j%j){
                    f=0;
                    break;
                }
            }
            if(f) return i<<1;
        }
        return 0;
    }
};

首先可以發現的一個很明顯的性質就是,答案不可能大於n*2,因爲如果m取到n*2,那麼對於1~n中的每個數都有它的兩倍,於是一定滿足A=B。正是由於這個性質,我纔想到了那種奇怪的方法。
以下都是看了題解之後的心得
可以單獨得看如何滿足每個元素。
當然這種情況,肯定是把元素拆分成素數來看,於是我們來看每一個素數。可以發現,對於一個素數的x次冪,我們只能通過把他乘二的數來保證答案是他的倍數。於是可以先把n以內的素數不斷乘自己,達到一個最大的x使得px<=n ,於是用px2 更新答案。
貼一下標程吧:

vector<int> get_primes(int N)
{
    // Sieve of Erathostenes to find all the necessary prime numbers:
    vector<int> res;
    vector<bool> composite(N + 1, false);

    for (int p = 2; p <= N; p++) {
        if (! composite[p]) {
            for (int i = p+p; i <= N; i += p) {
                composite[i] = true;
            }
            res.push_back(p);
        }
    }
    return res;

}

int get_exponent(int x, int p)
{
    int r = 0;
    while (x % p == 0) {
        r++;
        x /= p;
    }
    return r;
}

int getMin(int N)
{
    int res = 2;
    // For each prime number <= N:
    // 找到<=n的每個質數
    for (int p: get_primes(N) ) {
        // first find the maximum exponent of p  among numbers <= N
        // 找到p<=n的最大的冪
        int max_exp = 0;
        int i = p;
        while (i <= N) {
            max_exp = std::max(max_exp, get_exponent(i,p) );
            i += p;
        }
        // seek the minimum i such that get_exponent(i,p) >= max_exp:
        // 找到最小的i使得get_exponent(i,p)>=max_exp
        while (get_exponent(i,p) < max_exp) {
            i += p;
        }
        // the maximum for all ps is the result:
        // 最大的ps是答案。
        res = std::max(res, i);
    }
    return res;
}

順便說一句題外話,我居然在topcoder上看見一個代碼爲空的人AC了,於是我隨便交了一組數據上去,居然Challenge Successful了!什麼情況?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章