二进制枚举

题目链接: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;
}
原文地址:https://www.cnblogs.com/letlifestop/p/10262894.html