洛谷題單指南-數學基礎問題-P2926 [USACO08DEC] Patting Heads S

江城伍月發表於2024-04-10

原題連結:https://www.luogu.com.cn/problem/P2926

題意解讀:有n個數,計算每個數能整除其他數的個數。

解題思路:

a[100005]記錄所有的數,h[1000005]記錄所有數的個數,cnt[1000005]記錄所有數能整除其他數的個數

只需要讀入a陣列,同時更新h[a[i]]++

再依次從小到大遍歷h的下標每一個數i,如果h[i] > 0,則用類似於素數篩的方法,依次判斷i的倍數j = 2i,3i,4i....是否存在

如果h[j] > 0,就將cnt[j]++,說明j可以整除的數多了一個

注意相同的數可以有多個,也就是h[i]可能大於1,要記錄相同的數也能互相整除,可以把cnt[i]加上h[i] - 1,

例如:有兩個2,h[2] = 2,2能被2整除,cnt[2] += 1

100分程式碼:

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

const int N = 1e5 + 5, M = 1e6 + 5;

int a[N], h[M], cnt[M]; //a:每頭牛的數字  h:每個數字出現的次數 cnt:每個數字能整除的數字個數
int n, maxn;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) 
    {
        scanf("%d", &a[i]);
        h[a[i]]++;
        maxn = max(maxn, a[i]);
    }

    for(int i = 1; i <= maxn; i++)
    {
        if(h[i])
        {
            cnt[i] += h[i] - 1; //h[i]個相同的i,對於i可整除的數增加h[i] - 1
            for(int j = i + i; j <= maxn; j += i)
            {
                if(h[j]) cnt[j] += h[i];
            }
        }
    }

    for(int i = 1; i <= n; i++) printf("%d\n", cnt[a[i]]);
}

相關文章