hdu5223(GCD)

題目鏈接:點擊打開鏈接

題意:

首先給定數組中有多少個數,只告訴你他們最小值爲1,不告訴你每個數字是多少,要求根據給定區間中數的最大公約數,復原原來的序列。

思路:

先把所有的數初始化爲1,然後根據指定問題,如果某一區間的最大公約數是ans, 那麼這個區間中的所有數字都是ans的倍數,所以,把區間中的每個數字都賦值爲原數字和ans的最小公倍數即可。


這道題本來是一道水題,但由於自己的粗心而導致在比賽中一直是wrong answer。錯誤的原因就是數據類型用錯了。首先看到數據範圍是10的9次方,在int範圍內(int範圍是2的32次方比 4 乘以10的9次方多一點),所以我就考慮使用int行來保存數組中的所有數字,但由於在求最小公倍數是涉及到兩個數的乘法,所以有可能會超出int的範圍,本來很好處理的問題,但我竟然又聲明瞭一個long long int 的變量用來保存兩個int型數據的乘積,這樣做是愚蠢的,因爲兩個int型數據相乘時結果還是int型,用long long int 保存兩個int型數據的乘積就是先把兩個int型數據相乘的到的int型結果強制轉化爲long long int 而已, 在相乘中就會出現超出範圍的問題,即相乘的結果就是錯誤的,所以在賦值後,還是錯誤的。  

解決的辦法應該是先把兩個int型分別賦值到兩個long long int型變量中,然後把兩個long long int 型變量相乘後除以他們的最大公約數,最後檢查 這個數是否越界,如果不越界就可以賦值給對應的int型變量了。

代碼如下:

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;
const int MAXN= 1005;
int a[MAXN], l[MAXN], r[MAXN], ans[MAXN], n, q;
int gcd(int a, int b)
{
    int tem;
    while(b != 0)
    {
        tem = a % b;
        a = b;
        b = tem;
    }
    return a;
}
int scd(long long int a,long long int b)   //注意要用long long int 或 long int
{
        return (long long)(a*b)/gcd(a,b);
}
int newgcd(int l, int r)  //區間在l,r範圍的最大公約
{
    long long int i, tem = a[l];
    for(i = l+1; i <= r; i++)
    {
        tem = gcd(tem, a[i]);
    }
    return tem;
}
void init(int num)
{
    int i;
    for(i = 1; i <= num+2; i++)
    {
        a[i] = 1;
    }
}
int main()
{
    int i, j, t;
    bool ok;
    long long int tem;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &q);
        init(n);
        ok = true;
        for(i = 1; i <= q; i++)
        {
            scanf("%d%d%d", &l[i], &r[i], &ans[i]);
            if(ans[i] == 1)
                continue;
            for(j = l[i]; j <= r[i]; j++)
            {
<span style="white-space:pre">		</span>/*
                最初是這樣求最小公倍數的
                tem = a[j] * ans[i];    //如果乘積超過整型的範圍,賦值給tem的數還是錯誤的。
                a[j] = tem / gcd(a[j], ans[i]);
                */
                tem = scd(a[j], ans[i]);  //求最小公倍數
                if(tem > 1000000000)     //注意題中的條件,做題容易只考慮下界而不考慮上界。
                {
                    ok =false;
                    break;
                }
                else
                {
                    a[j] = tem;
                }
            }
        }
        if(ok != false)
        {
            for(i = 1; i <= q; i++)
            {
                if(newgcd(l[i], r[i]) != ans[i])
                {
                    ok = false;
                    break;
                }
            }
        }
        if(ok)
        {
            for(i = 1; i < n; i++)
            {
                printf("%d ", a[i]);
            }
            printf("%d\n", a[i]);
        }
        else
        {
            printf("Stupid BrotherK!\n");
        }
    }
    return 0;
}


109109


發佈了31 篇原創文章 · 獲贊 12 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章