AtCoder題解——Beginner Contest 169——B - Multiplication 2

題目相關

題目鏈接

AtCoder Beginner Contest 169 B題,https://atcoder.jp/contests/abc169/tasks/abc169_b

Problem Statement

Given N integers A1,...,AN compute A1×...×AN.

However, if the result exceeds 10^18, print -1 instead.

Input

Input is given from Standard Input in the following format:

N
A1 ... An

Output

Print the value A1×...×AN as an integer, or -1 if the value exceeds 10^18.

Samples1

Sample Input 1

2
1000000000 1000000000

Sample Output 1

1000000000000000000

Explaination

We have 1000000000×1000000000=1000000000000000000.

Samples2

Sample Input 2

3
101 9901 999999000001

Sample Output 2

-1

Explaination

We have  101×9901×999999000001=1000000000000000001, which exceeds 10^18, so we should print -1 instead.

Samples3

Sample Input 3

31
4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0

Sample Output 3

0

Constraints

  • 2 ≤ N ≤ 10^5
  • 0 ≤ Ai ≤10^18
  • All values in input are integers.

題解報告

本題含義

給了 N 個數,要求我們計算這 N 個數的乘積。但是這個乘積有個限制,如果乘積超過 10^18 這個數,我們就要輸出 -1。

樣例數據分析

本題的難度不大。樣例數據 1 和樣例數據 2 沒有什麼需要分析的地方。我們要重點觀察一下樣例數據 3。

我們不難發現 4*1*5*9*2*6*5*3*5*8*9*7*9*3*2*3*8*4*6*2*6*4*3*3*8*3*2*7*9 已經超過了 10^18。但是題目給出的參考答案是 0。

也就是說,本樣例數據是一個卡人的地方。就是說如果輸入數據中有 0 存在,不管如何乘積的結果都不會超過 10^18。

所以本題不能直接讀入數據累乘進行判斷。

本題的難點

我們知道在 C++ 中,unsigned long long 的最大值是 2^64-1,也就是1.84*10^19。因此本題的難點在於如何判斷兩個數乘積超過了 unsigned long long 的範圍,也就是數據越界。

判斷兩個數乘積是否超過數據的表示範圍,我們可以用除法。假設兩個數分別爲 a 和 b,我們只需要用:最大值 / a 和 b 進行比較即可。如果 最大值 / a 小於 b,說明越界;否則不越界。

這個我們可以非常輕鬆的用一個簡單數字來說明。如果 a 和 b 都是正數,而且 a*b 的值不能超過 10。那麼當 a = 5 的時候,b 的取值範圍只能是:0、1、2,這三個數。因此 10/5=2。

解決了這個判斷,本題就很容易了。

算法設計

1、讀入 N 個數據。如果數據中有零,直接輸出答案。

2、從第一個數據開始累乘,判斷乘積是否會超過 unsigned long long 的表示範圍或者超過 10^18。

AC 參考代碼

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 2e5+2;
unsigned long long nums[MAXN];

const long long MAXL = 1e18;

//判斷a*b是否超過1e18
bool overflow(unsigned long long a, unsigned long long b) {
    //判斷是否越界
    if (ULLONG_MAX / a < b) {
        return true;
    }
    //判斷是否超過1e18
    unsigned long long ans = a*b;
    if (ans>MAXL) {
        return true;
    }
    return false;
}

int main() {
    int n;
    scanf("%d", &n);
    for (int i=0; i<n; i++) {
        scanf("%llu", &nums[i]);
        if (0==nums[i]) {
            printf("0\n");
            return 0;
        }
    }

    long long ans=1;
    for (int i=0; i<n; i++) {
        if (true == overflow(ans, nums[i])) {
            printf("-1\n");
            return 0;
        }
        ans *= nums[i];
    }

    printf("%llu", ans);

    return 0;
}

 

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