nyoj 881 小M的區間公約數

點擊打開連接php


首先給的範圍很大,是10^9。暴力解確定超時(單用for循環到10^9都大約要2s-3s),首先寫了個程序暴力的把兩個數全部的約數都打印出來,最後發現全部的公約數都是最大公約數的約數,而且最大公約數的約數也必定是兩個數的公約數,由此題目轉換爲求最大公約數的約數的問題,覺得輸入最大是10^9,因此公約數最大是5*10^8,求這個數的全部約數只須要循環到(跟號5)*10^4,for循環能夠輕鬆應對了,直接用for獲得全部的約數,而後qsort排序後,把數組的結構抽象成數軸上的n多個點,每一個點都是這兩個數的約數了,剩下的工做就是從大到小循環全部的公約數找第一個在查詢區間裏的約數就是要求的解。數組

附上AC代碼:.net

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int gcd(int a, int b)
{
    if(b == 0)
        return a;
    else 
        return gcd(b, a % b);
}
int cmp(const void *a, const void *b)
{
    return *(int *)b - *(int *)a;
}
int array[10000];
int top;
int main()
{
    int a, b;
    while(scanf("%d %d", &a, &b) != EOF)
    {
        memset(array, 0, sizeof(array));
        top = 0;
        int n;
        if(a < b)
        {
            int swap = a;
            a = b;
            b = swap;
        }
        int max = gcd(a, b);
        int i;
        for(i = 1; i * i < max; i++)
        {
            if(max % i == 0)
            {
                array[top++] = i;
                array[top++] = max / i;
            }
        }
        if(i * i == max)
            array[top ++] = i;
        qsort(array, top, sizeof(int), cmp); 
        scanf("%d", &n);
        while(n--)
        {
            int l, r;
            scanf("%d %d", &l, &r);
            int k;
            if(l > max)
            {
                printf("-1\n");
                continue;
            }
            for(k = 0; k < top; k++)
            {
                if(l <= array[k] && r >= array[k])
                {
                    printf("%d\n", array[k]);
                    break;
                }
                else if(l > array[k])
                {
                    printf("-1\n");
                    break;
                }
            }
        }
    }
    return 0;
}
相關文章
相關標籤/搜索