zoukankan      html  css  js  c++  java
  • CF Gym 100463B Music Mess (思路)

    好题,当时想了半个小时,我往图论方面去想了,把出现过的字符串当场点,然后相互连边,那么就构成了一个三角形,一个大于三个点的连通分量里有以下结论:度为二的点可能是track,度为大于二的点一定不是track,当一个点连接一个可能是track的点和一个可能是artist的点,那么这个点就可能是ablum。然后我就卡在这里了,怎么求连通分量,怎么判断一个点一定是artist。还有形成的树的深度不能超过三,等等问题。

    其实这样想不对,借助之前做A Lot of Joy 的思想,改下一思路,判断连通改成统计以下它在出现的次数。然后一个三元组一个三元组的考虑。考虑他们出现的次数,

    有个结论:出现次数:artist>=album>=track

    如果三个相等,那么就他们三个是可以相互替换的。如果两个出现次数多的结点次数相等,那么次数少的那个一定是作为track,剩下两个既可以当成track也可以当成artist;如果出现次数少的两个结点次数相等,那个次数多那个一定是artist,剩下两个既可以当成album也可以当成track。

    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    //#include<iostream>
    #include<string>
    #include<cstring>
    
    using namespace std;
    
    //#define local
    const int maxn = 10005;
    
    
    map<string,int> mp;
    int vcnt;
    int ID(const string & x)
    {
        if(mp.count(x) == 0){
            mp.insert(make_pair(x,vcnt));
            return vcnt++;
        }
        else return mp[x];
    }
    
    int cnt[maxn*3];
    int smp[maxn][3];
    int vec[3][maxn*9],sz[3];
    
    void init(){
        vcnt = 0;
        memset(cnt,0,sizeof(cnt));
        ans[0].clear();
        ans[1].clear();
        ans[2].clear();
    }
    
    bool cmp(int a,int b) { return cnt[a]<cnt[b]; }
    
    
    int main()
    {
    #ifdef local
        freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
    #endif // local
        char buf[100];
        int N;
        int cas = 0;
        while(~scanf("%d",&N)&&N){
            init();
            for(int i = 0; i < N; i++){
                for(int j = 0; j < 3; j++){
                    scanf("%s",buf);
                    smp[i][j] = ID(buf);
                    cnt[smp[i][j]]++;
                }
            }
            mp.clear();
            for(int i = 0; i < N; i++){
                sort(smp[i],smp[i]+3,cmp);
                int tmp[3] = { cnt[smp[i][0]],cnt[smp[i][1]],cnt[smp[i][2]] };
                if(tmp[2] == tmp[0]){
                    for(int k = 0; k < 3; k++)
                        for(int j = 0; j < 3 ;j++ ) {
                            ans[k].insert(smp[i][j]);
                        }
                }else {
                    if(tmp[1] == tmp[0]){
                      ans[0].insert(smp[i][2]);
                      ans[1].insert(smp[i][1]); ans[1].insert(smp[i][0]);
                      ans[2].insert(smp[i][1]); ans[2].insert(smp[i][0]);
                    } else if(tmp[2] == tmp[1]) {
                        ans[2].insert(smp[i][0]);
                        ans[1].insert(smp[i][1]); ans[1].insert(smp[i][2]);
                        ans[0].insert(smp[i][1]); ans[0].insert(smp[i][2]);
                    } else {
                        ans[0].insert(smp[i][2]);
                        ans[1].insert(smp[i][1]);
                        ans[2].insert(smp[i][0]);
                    }
                }
            }
    
            printf("Case %d: %d %d %d
    ",++cas,ans[0].size(),ans[1].size(),ans[2].size());
        }
        return 0;
    }
  • 相关阅读:
    关于通胀,交易手续费和加密货币的货币政策
    私有链和联盟链的机会与挑战
    耶鲁大学公开课:博弈论第九节(笔记)
    区块链匿名技术
    区块链对比数据库
    硬盘 分区 格式化 和挂载
    Nginx实战系列之功能篇----后端节点健康检查
    Nginx实战系列之功能篇----后端节点健康检查
    Nginx实战系列之功能篇----后端节点健康检查
    Nginx实战系列之功能篇----后端节点健康检查
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4665749.html
Copyright © 2011-2022 走看看