• Topcoder SRM 584 DIV2 解题报告


    ------------

    250 TopFox

    给两个字符串,求有多少种不同的前缀和。

    ----

    直接枚举前缀,压入set即可。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <set>
    using namespace std;
    
    class TopFox{
        public:
            int possibleHandles(string a,string b)
            {
                int ans;
                set<string>st;
                for (int i=0;i<a.size();i++)
                {
                    for (int j=0;j<b.size();j++)
                    {
                        st.insert(a.substr(0,i+1)+b.substr(0,j+1));
                    }
                }
                ans=st.size();
                return ans;
            }
    };
    
    ------------

    500 Egalitarianism

    有n个人,他们之间有些人互为朋友,朋友之间money之差不能超出d。

    求最大的money差,没有则输出-1。

    ----

    先判断图是否连通。

    然后枚举每个人为起点,设money为0,各做一次bfs求出最大money。O(n*n)

    输出最大的money即可。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    
    using namespace std;
    
    const int maxn=55;
    
    class Egalitarianism{
        private:
            bool a[maxn][maxn];
            int money[maxn];
            int n;
            int ans;
            bool vis[maxn];
            queue<int>que;
    
            void init()
            {
                ans=0;
                memset(a,0,sizeof(a));
                memset(vis,0,sizeof(vis));
                memset(money,0,sizeof(money));
            }
    
            void dfs_vis(int u)
            {
                vis[u]=true;
                for (int i=0;i<n;i++)
                    if (a[u][i]&&!vis[i]) dfs_vis(i);
            }
    
            bool check_vis()
            {
                for (int i=0;i<n;i++)
                    if (!vis[i]) return false;
                return true;
            }
    
            void bfs(int u)
            {
                while (!que.empty()) que.pop();
                memset(vis,0,sizeof(vis));
                que.push(u);
                vis[u]=true;
                while (!que.empty())
                {
                    int t=que.front();
                    que.pop();
                    ans=max(ans,money[t]);
                    for (int i=0;i<n;i++)
                    {
                        if (!vis[i]&&a[t][i])
                        {
                            que.push(i);
                            vis[i]=true;
                            money[i]=money[t]+1;
                        }
                    }
                }
            }
    
        public:
            int maxDifference(vector <string> isFriend, int d)
            {
                init();
                n=isFriend.size();
                for (int i=0;i<n;i++)
                    for (int j=0;j<n;j++)
                        if (isFriend[i][j]=='Y')
                        {
                            a[i][j]=true;
                            a[j][i]=true;
                        }
                dfs_vis(0);
                if (!check_vis()) return -1;
                for (int i=0;i<n;i++)
                {
                    memset(money,0,sizeof(money));
                    bfs(i);
                }
                ans*=d;
                return ans;
            }
    };

    ------------

    1000 Excavations2

    给一个序列kind有重复元素,一个集合found无重复元素,一个K。

    问从kind中取出K个元素, 这些元素去重后恰为集合found,共有多少种取法。

    ----

    实在不懂数论,所以直接暴力求解了。。

    搜索出所有可能的值。。

    卡时间险过。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    
    using namespace std;
    
    class Excavations2{
        private:
            long long ans;
            int n;
            int num[55];
            long long c[55][55];
            int a[55];
            int f[55];
            long long myc(int n,int r)
            {
                if (c[n][r]!=0) return c[n][r];
                long long sum=1;
                for (int i=1;i<=r;i++)
                    sum=sum*(n+1-i)/i;
                c[n][r]=sum;
                return sum;
            }
            void dfs(int sp,int h)
            {
                if (h<0) return;
                if (n-sp-1>h) return;
                if (sp>=n&&h>0) return;
                if (sp==n)
                {
                    long long tmp=1;
                    for (int i=0;i<n;i++)
                        tmp*=myc(num[f[i]],a[i]);
                    ans+=tmp;
                    return;
                }
                for (int i=1;i<=num[f[sp]];i++)
                {
                    a[sp]=i;
                    dfs(sp+1,h-i);
                }
            }
        public:
        long long count(vector<int> kind, vector<int> found, int K)
        {
            memset(num,0,sizeof(num));
            memset(c,0,sizeof(c));
            memset(a,0,sizeof(a));
            n=found.size();
            for (int i=0;i<n;i++) f[i]=found[i];
            for (int i=0;i<kind.size();i++) num[kind[i]]++;
            ans=0;
            dfs(0,K);
            return ans;
        }
    };
    


    ------------

  • 相关阅读:
    [ZJOI2010]count 数字计数
    小雄数
    简单筛法函数
    [Noip模拟题]lucky
    欧拉线筛
    Intern Day78
    CodeForces1360C
    CodeForces1373B
    Intern Day78
    Intern Day78
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226285.html
Copyright © 2020-2023  润新知