您的位置:首页 > 其它

CF Gym 100463B Music Mess (思路)

2015-07-22 09:50 302 查看
好题,当时想了半个小时,我往图论方面去想了,把出现过的字符串当场点,然后相互连边,那么就构成了一个三角形,一个大于三个点的连通分量里有以下结论:度为二的点可能是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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: