問題
http://community.topcoder.com/stat?c=problem_statement&pm=8444&rd=11120
解き方
ビット列ですべての組み合わせについて調べれば良い。
ただし、その部分集合で満たすものがあれば偽になるので
これまで調べたビット列で真のものを保存して、含まれないか判定する。
ビット列は順番に調べていけばそれまでの値は必ず含まれるので問題ない。
コード
class CandidateKeys {
public: vector<int> getKeys(vector<string> table) {
int n=table.size(),m=table[0].size();
int valid=0;
vector<int> ans(2);
ans[0]=1e+9,ans[1]=0;
vector<int> vx;
for(int mask=1;mask<(1<<m);mask++){
set<string> s;
FORE(i,0,n){
string str="";
FORE(j,0,m)if(mask&(1<<j))str+=table[i][j];
s.insert(str);
}
if(s.size()==n){
valid=1;
int can=1;
FORE(i,0,vx.size())if((vx[i]&mask)==vx[i])can=0;
if(can){
ans[0]=min(ans[0],__builtin_popcount(mask));
ans[1]=max(ans[1],__builtin_popcount(mask));
vx.push_back(mask);
}
}
}
return valid ? ans : vector<int>();
}
};
public: vector<int> getKeys(vector<string> table) {
int n=table.size(),m=table[0].size();
int valid=0;
vector<int> ans(2);
ans[0]=1e+9,ans[1]=0;
vector<int> vx;
for(int mask=1;mask<(1<<m);mask++){
set<string> s;
FORE(i,0,n){
string str="";
FORE(j,0,m)if(mask&(1<<j))str+=table[i][j];
s.insert(str);
}
if(s.size()==n){
valid=1;
int can=1;
FORE(i,0,vx.size())if((vx[i]&mask)==vx[i])can=0;
if(can){
ans[0]=min(ans[0],__builtin_popcount(mask));
ans[1]=max(ans[1],__builtin_popcount(mask));
vx.push_back(mask);
}
}
}
return valid ? ans : vector<int>();
}
};