好题,当时想了半个小时,我往图论方面去想了,把出现过的字符串当场点,然后相互连边,那么就构成了一个三角形,一个大于三个点的连通分量里有以下结论:度为二的点可能是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; }