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;

}

 

你可能感兴趣的:(Music)