L3-003ソーシャルクラスター(30ポイント)(2つのアイデア)

ソーシャルネットワークプラットフォームに登録するとき、同じ趣味を持つ潜在的な友人を見つけるために、通常は常に個人的な趣味を記入するように求められます。「ソーシャルクラスター」とは、同じ興味や趣味を持つ人々の集まりを指します。すべてのソーシャルクラスターを見つける必要があります。

入力形式:
最初の行に正の整数N(≤1000)を指定して、ソーシャルネットワークプラットフォームに登録されているすべてのユーザーの数を入力しますしたがって、これらの人々には1からNまでの番号が付けられます。次のN行では、各行に次の形式で人の趣味のリストが表示されます。

K i:h i [1] h i [2]…hi [K i]ここで、K i(> 0)は趣味の番号です。 hi i [j]はj番目の趣味の番号であり、区間[1、1000]の整数です。

出力形式:
最初に、1行に異なるソーシャルクラスターの数を出力します次に、2行目は、各クラスターの人数を昇順ではなく出力します。数字はスペースで区切られ、行末に余分なスペースがあってはなりません。

入力サンプル:

8
3:2 7 10
1:4
2:5 3
1:4
1:3
1:4
4:6 8 1 5
1:4

サンプル出力:

3
4 3 1

非統合バージョン、20ポイントのコード、何が問題なのかがわかりません
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

bool vis[1001] = {
    
    false};

bool cmp(int a, int b) {
    
     return a > b; }

int main() {
    
    
    int n, k, id, cnt = 0;
    char ch;
    cin >> n;
    int a[n + 1] = {
    
    0};
    vector<int> v[n + 1];
    for (int i = 1; i <= n; i++) {
    
    
        cin >> k >> ch;
        bool flag = true;
        vector<int> vv;
        while (k--) {
    
    
            cin >> id;
            vv.push_back(id);
            if (vis[id]) {
    
    
                flag = false;
                bool x = false;
                for (int j = 1; j <= i - 1; j++) {
    
    
                    for (int p = 0; p < v[j].size(); p++) {
    
    
                        if (id == v[j][p]) {
    
    
                            a[j]++;
                            x = true;
                            break;
                        }
                    }
                    if (x)
                        break;
                }
            }
        }
        if (flag) {
    
    
            for (int x = 0; x < vv.size(); x++) {
    
    
                vis[vv[x]] = true;
                v[i].push_back(vv[x]);
            }
            cnt++;
            a[i]++;
        }
    }
    cout << cnt << endl;
    bool judge = true;
    sort(a + 1, a + n + 1, cmp);
    for (int i = 1; i <= n; i++) {
    
    
        if (a[i]) {
    
    
            if (judge) {
    
    
                cout << a[i];
                judge = false;
            } else {
    
    
                cout << " " << a[i];
            }
        } else {
    
    
            break;
        }
    }
    return 0;
}
複合小切手版、30点。複合小切手を考えたのですが、うまくいきませんでした。最初は、どのようにマージするか考えていなかったので、複合小切手で書くのに問題がありました。
#include <algorithm>
#include <iostream>
using namespace std;

int f[1001];
int flag[1001];
int num[2002];
int n;

bool cmp(int a, int b) {
    
     return a > b; }

void init() {
    
    
    for (int i = 1; i <= n; i++) {
    
    
        f[i] = i;
    }
}

int find(int x) {
    
    
    if (x == f[x])
        return x;
    return f[x] = find(f[x]);
}

void merge(int x, int y) {
    
    
    int a = find(x);
    int b = find(y);
    if (a != b)
        f[b] = a;
}

int main() {
    
    
    cin >> n;
    init();
    int k, id;
    char ch;
    for (int i = 1; i <= n; i++) {
    
    
        cin >> k >> ch;
        for (int j = 0; j < k; j++) {
    
    
            cin >> id;
            if (!flag[id])
                flag[id] = i;
            else
                merge(i, flag[id]);
        }
    }
    for (int i = 1; i <= n; i++) {
    
    
        int x = find(i);
        num[x]++;
    }
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
    
    
        if (num[i])
            cnt++;
    }
    cout << cnt << endl;
    sort(num + 1, num + n + 1, cmp);
    cout << num[1];
    for (int i = 2; i <= n; i++) {
    
    
        if (num[i])
            cout << " " << num[i];
        else
            break;
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/weixin_45845039/article/details/112606777