zoukankan      html  css  js  c++  java
  • HDU 5908 Abelian Period 可以直接用multiset

    http://acm.hdu.edu.cn/showproblem.php?pid=5908

    要求把数组分成k组使得每组中的元素出现次数相同

    就是分成k个集合,那么直接用multiset判定就可以

    有重载相等运算符的

    我被坑了的就是,

    对于2个元素一个集合的可以,那么,4,6,8这样分集合也是可以的。

    这个很容易理解

    但是,你也要能平均分才行啊

    就是10的2可以,但是4是一定不可以得。不能平均分

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 100000 + 20;
    int a[maxn];
    multiset<int>aa;
    multiset<int>bb;
    set<int>ans;
    void work() {
        aa.clear();
    //    bb.clear();
        ans.clear();
        int n;
        scanf("%d", &n);
        bool flag = true;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            if (i >= 2 && a[i] != a[i - 1]) flag = false;
        }
        ans.insert(n);
        if (flag) {
            for (int i = 1; i <= n / 2; ++i) {
                if (n % i == 0) {
                    ans.insert(i);
                }
            }
        } else {
            int begin = 1, end = -1;
            for (int i = 2; i <= n / 2; ++i) {
                if (n % i != 0) continue;
                if (ans.find(i) != ans.end()) continue;
    //            aa.clear();
                end = i;
    //            cout << begin << " " << end << " " << i << endl;
                for (int j = begin; j <= end; ++j) {
                    aa.insert(a[j]);
                }
                begin = end + 1;
                flag = true;
                for (int j = 2 * i; j <= n; j += i) {
                    bb.clear();
                    for (int k = j; k >= j - i + 1; --k) {
                        bb.insert(a[k]);
                    }
                    if (aa != bb) {
                        flag = false;
                        break;
                    }
                }
                if (!flag) continue;
                for (int j = i ; j <= n / 2; j += i) {
                    if (n % j == 0) //10的2不代表10的4
                        ans.insert(j);
                }
            }
        }
    //    show();
        set<int> :: iterator it = ans.begin();
        printf("%d", *it);
        it++;
        for (; it != ans.end(); ++it) {
            printf(" %d", *it);
        }
        printf("
    ");
        return;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        int t;
        scanf("%d", &t);
        while(t--) work();
        return 0;
    }
    View Code
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 100000 + 20;
    int a[maxn];
    bool isok[maxn];
    int n;
    int cnt[maxn];
    int cmp[maxn];
    bool check(int val) {
        for (int i = 1; i <= val; ++i) {
            cnt[a[i]] = 0;
        }
        for (int i = 1; i <= val; ++i) {
            cnt[a[i]]++;
        }
        for (int i = 2 * val; i <= n; i += val) {
            for (int j = i; j >= i - val + 1; --j) {
                cmp[a[j]] = 0;
            }
            for (int j = i; j >= i - val + 1; --j) {
                cmp[a[j]]++;
            }
            for (int j = 1; j <= val; ++j) {
                if (cnt[a[j]] != cmp[a[j]]) return false;
            }
        }
        return true;
    }
    void work() {
        scanf("%d", &n);
        bool flag = true;
        memset(isok, 0, sizeof isok);
        isok[n] = 1;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            if (i >= 2 && a[i] != a[i - 1]) flag = false;
        }
        if (flag) {
            for (int i = 1; i <= n / 2; ++i) {
                if (n % i == 0) {
                    isok[i] = 1;
                }
            }
        } else {
            for (int i = 2; i <= n / 2; ++i) {
                if (n % i != 0 || isok[i]) continue;
                if (check(i)) {
                    for (int j = i; j <= n / 2; ++j) {
                        if (n % j == 0) isok[i] = 1;
                    }
                }
            }
        }
        flag = 0;
        for (int i = 1; i <= n; ++i) {
            if (isok[i]) {
                if (!flag) {
                    printf("%d", i);
                    flag = 1;
                } else {
                    printf(" %d", i);
                }
            }
        }
        printf("
    ");
        return;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        int t;
        scanf("%d", &t);
        while(t--) work();
        return 0;
    }
  • 相关阅读:
    c#使用selenium过滑动验证码
    C#构建数据类型不同的链表
    【疑难杂症】c#控制台应用程序卡输出
    只需三步,轻松体验office2019
    一文搞定C#.Net如何调用/交互Javascript
    逆向某微信小程序参数签名算法
    win10 IIS疑难杂症--处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler”
    一台手机如何在微信语音/视频通话时把声音录下来
    android端日志查看调试利器Logcat Reader
    [开源]安卓调试神器-获取最上层Activity:TopActivity
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5926729.html
Copyright © 2011-2022 走看看