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\n",++cas,ans[0].size(),ans[1].size(),ans[2].size());
    }
    return 0;
}

 

posted @ 2015-07-22 09:50  陈瑞宇  阅读(290)  评论(2编辑  收藏  举报