能否被8整除

題目:給定一個非負整數,問能否重排它的全部數字,使得重排後的數能被8整除。 輸入格式: 多組數據,每組數據是一個非負整數。非負整數的位數不超過10000位。 輸出格式 每組數據輸出一行,YES或者NO,表示能否重排它的全部數字得到能被8整除的數。注意: 重排可以讓0開頭。


思路:

  • 考慮到64位整型可以直接取餘8求得結果,所以當輸入非負整數位數小於20位的時候,可以直接轉換成64位整型進行計算。
  • 對於一個非負整數,最後四位相當於是 p*1000 + x*100 + y*10 + z ,可以很顯然的看出p*1000必然能被8整除,所以一個非負整數只需要後三位能被8整除,那麼這個數就一定能被8整除。所以如果我們能從這個數中任意取出三位,作爲最後三位,其值能被8整除,就輸出YES,否則NO。
  • 沒必要對可能的10000位做全排列,因爲0-9每個數最多隻能用3次,我們只需要遍歷一遍每一位,將0-9出現的次數記錄下來,最多允許記錄3次。這樣最壞的情況下需要對30個數進行全排列即可,效率會非常高。


代碼:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>

#define MAX 10001

int has_num[10];    //0-9在這個數中出現的次數

bool check()
{
    int deal_num[30];   //0-9每個數最多可以用3次,只需要30的空間
    int n = 0;
    //將所有出現過數依次存放在deal_num數組中
    for (int i=0; i<10; i++) {
        for (int j=0; j<has_num[i]; j++) {
            deal_num[n] = i;
            n++;
        }
    }

    //排列任意三個數組成一個整數,其值能被8整除,返回true,否則false
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
            if (j == i)
                continue;
            for (int k=0; k<n; k++) {
                if (k == i || k == j) {
                    continue;
                }
                if ((deal_num[i]*100 + deal_num[j]*10 + deal_num[k]) % 8 == 0)
                    return true;
            }
        }
    }
    return false;
}

int main()
{
    char str_num[MAX];  //用於保存不超過10000位的整數
    int n;
    long long temp = 0; //如果位數小於等於19,直接轉換爲64位整型

    for (;;) {
        memset(str_num, 0, sizeof(str_num));
        for (int i=0; i<10; i++) {
            has_num[i] = 0;
        }
        if (scanf("%s", &str_num) == 1) {
            n = strlen(str_num);
            //轉換爲64位整型
            if (n <= 19) {
                sscanf(str_num, "%lld", &temp);
                if ((temp % 8) == 0)
                    printf("YES\n");
                else
                    printf("NO\n");
                continue;
            }
            
            //將0-9出現的次數保存在has_num數組中,最多3次
            for (int i=0; i<n; i++) {
                if (has_num[(int)str_num[i] - 48] < 3)
                    has_num[(int)str_num[i] - 48]++;
            }
            if (check())
                printf("YES\n");
            else
                printf("NO\n");
            continue;

        } else {
            break;
        }
    }
    return 0;
}


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