hdu2609-字符串最小表示法|模拟|二分+lcp-How many

来源:互联网 发布:现货交易软件哪个好 编辑:程序博客网 时间:2024/05/21 17:50

http://acm.hdu.edu.cn/showproblem.php?pid=2609
给你m个串,长度相等。只有0和1组成,
他们都可以把后面的 放在前面。并且这种串算作相同的
比如 1100 1001 0011 0110 这四个。
问你m个中有多少不同的。
暴力写的,后来看别人的题解。最小表示法,O(n),,类似用两个指针 来比较,利用的是 字典序的相关特质,
还有一个lcp+二分的,先mark。

#include <bits/stdc++.h>using namespace std;/* 或者用 字符串的最小表示法。  用来解决字符串的同构问题。  同构即 一个字符串最后面的移动到前面,然后  形成总共 (长度len)个 串,这些串同构。*/const int maxn=2e5;int  MINR(string s){    int len=s.length();    int i=0;int j=1;    //int k=0;    while(i<len/2&&j<len/2){          int k=0;          while(s[i+k]==s[j+k]&&k<len/2) k++;           if(k==len/2) return min(i,j);           if(s[i+k]>s[j+k])// 若求最大,把大于改成小于,下面也是。              i=max(i+k+1,j+1);          else if(s[i+k]<s[j+k])              j=max(j+k+1,i+1);    }    return min(i,j);}int main(){    int t;    string s[maxn];     vector<string>w;    while(~scanf("%d",&t)){          w.clear();          for(int i=0;i<t;i++){             cin>>s[i];             s[i]+=s[i];          }          for(int i=0;i<t;i++){              int r=MINR(s[i]);              //cout<<r<<endl;              //cout<<s[i].substr(r,s[i].length()/2)<<endl;              w.push_back(s[i].substr(r,s[i].length()/2));          }          sort(w.begin(),w.end());          w.erase(unique(w.begin(),w.end()),w.end());          /*for(int i=0;i<w.size();i++){             cout<<w[i]<<endl;          }*/          printf("%d\n",w.size());    }    return 0;}

暴力。比那个慢点
bitset应该也行,不过得自己写。。

#include <bits/stdc++.h>using namespace std;/* bitset模拟。   srting*/const int maxn=1e5;int main(){    int n;      string s[maxn];     set<string>se;    while(cin>>n){          se.clear();          for(int i=0;i<n;i++){             cin>>s[i];             s[i]+=s[i];             //s[i]+=s[i];            // cout<<s[i]<<endl;          }         // cout<<s[0][0]<<endl;          vector<string> kk;          for(int i=0;i<n;i++){             {   kk.clear();                for(int j=0;j<s[i].length()/2;j++){                 //cout<<s[i][j]<<endl;                 string w=s[i].substr(j,s[i].length()/2);                 //cout<<w<<endl;                   kk.push_back(w);                 }                 sort(kk.begin(),kk.end());                 //cout<<kk[0]<<endl;                  se.insert(kk[0]);             }          }          //set<string>::iterator it;          //for(it=se.begin();it!=se.end();it++)           // cout<<*it<<endl;          printf("%d\n",se.size());    }    return 0;}
原创粉丝点击