二进制枚举
题目链接:http://hihocoder.com/problemset/problem/1829
AC代码:
二进制枚举一定要注意边界,打个比方,已知一个字符串的长度是3,而你要枚举这个字符串的递增的子串的所有情况,也就是说三位数枚举。000,001,010,100,110,101,011,111,210.这就是所有的情况(2的n(n代表长度)次方),因为字符串不能为空,所以将000这种情况去掉。可以看到,最大的值是111,这个时候的值是7而不是8,一定要注意。
#include<bits/stdc++.h>
using namespace std;
map<string,int >vis;
map<string,int >cnt;
vector<string>q;
string s1,temp;
string s;
void change(int t)
{
temp.clear();
s1.clear();
temp=s.substr(t);//substr函数的作用,如果只有一个参数,就截取当前参数一直到末尾的字符串
s1+=temp;
temp=s.substr(0,t);//两个参数的时候就限制起点和终点
s1+=temp;
}
bool cmp(string t1,string t2)
{
if(t1.size()!=t2.size())return t1.size()>t2.size();
else return t1<t2;
}
int main()
{
ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
int w=n;
q.clear();
cnt.clear();
while(n--)
{
vis.clear();
cin>>s;
int len=s.size();
for(int i=0; i<len; i++)
{
change(i);
string t;
for(int j=1; j<(1<<len); j++)//这个地方一定要注意边界
{
for(int k=0; k<len; k++)
{
if((j>>k)&1)
t+=s1[k];
}
if(vis[t]==0)
{
// cout<<t<<endl;
vis[t]=1;
cnt[t]++;
// if(cnt[t]==2)
// cout<<t<<endl;
}
t.clear();
}
}
}
int k=0;
for(auto u: cnt)
{
if(u.second==w)
{
k=1;
q.push_back(u.first);
// cout<<u.first<<endl;
}
}
sort(q.begin(),q.end(),cmp);
if(k==0)cout<<0<<endl;
else cout<<q[0]<<endl;
}
return 0;
}