标签:amp ring after ati stage stdin turn out 字符串数组
给你一个n*m的字符矩阵,将横向(或纵向)全部裂开,然后以任意顺序首尾相接,然后再从中间任意位置切开,问你能构成的字典序最大的字符串。
以横向切开为例,纵向类似。
将所有横排从大到小排序,枚举最后切开的位置在哪一横排,将这一排提到排序后的字符串数组最前面,求个“最大表示法”,如果最大表示法的位置恰好在第一排的位置,那么可以用来更新答案。
如果不在第一排的位置,那么其所构成的仍然是合法的串,而且一定不会影响答案。
这是一个最小表示法的板子。
#include<cstdio> #include<iostream> #include<string> #include<algorithm> using namespace std; string a[105],ans,b[105]; int n,m; bool cmp(const string &a,const string &b){ return a>b; } int MaxRep(string s, int l) { int i,j,k; i=0;j=1;k=0; while(i<l&&j<l) { k=0; while(s[i+k]==s[j+k]&&k<l) k++; if(k==l) return i; if(s[i+k]<s[j+k]) //??3é′óóú?íê?×?D?±íê? if(i+k+1>j) i=i+k+1; else i=j+1; else if(j+k+1>i) j=j+k+1; else j=i+1; } if(i<l) return i; else return j; } int main(){ // freopen("f.in","r",stdin); scanf("%d%d",&n,&m); for(int i=0;i<n;++i){ cin>>a[i]; } for(int i=0;i<n;++i){ for(int j=0;j<m;++j){ b[j]+=a[i][j]; } } sort(a,a+n,cmp); for(int i=0;i<n;++i){ string t=a[i]; for(int j=0;j<n;++j){ if(j!=i){ t+=a[j]; } } // cout<<i<<": "<<t<<‘ ‘; int p=MaxRep(t,n*m); string pre=t.substr(0,p); t.erase(0,p); t+=pre; // cout<<t<<endl; ans=max(ans,t); } sort(b,b+m,cmp); for(int i=0;i<m;++i){ string t=b[i]; for(int j=0;j<m;++j){ if(j!=i){ t+=b[j]; } } // cout<<i<<": "<<t<<‘ ‘; int p=MaxRep(t,n*m); string pre=t.substr(0,p); t.erase(0,p); t+=pre; // cout<<t<<endl; ans=max(ans,t); } for(int i=0;i<n*m;++i){ if(i!=‘0‘){ for(int j=i;j<n*m;++j){ putchar(ans[j]); } puts(""); return 0; } } return 0; }
标签:amp ring after ati stage stdin turn out 字符串数组
原文地址:http://www.cnblogs.com/autsky-jadek/p/7287013.html