2019牛客多校训练(七)
比赛链接:
https://ac.nowcoder.com/acm/contest/887#question
A.String
题意:
把字符串拆分成最少的段
每段字符串循环移位后最小字典序是原字符串
分析:
当时是贪心合并字符串,感觉可行,一直wa
00101001这样的字符串是不可行的
0010100101但是这样反而可行了
这题是用到了最暴力的解法,先从左往右枚举起点,从右往左枚举终点,再$O(n^2)$判断是否可行
首先这样的策略肯定是分解成了最少子段
但是怀疑它会超时,没敢写,结果居然可行
ac代码:
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn =200+7; char s[maxn]; bool check(int st,int en) { int len=en-st+1; for(int i=st+1;i<=en;i++){ for(int j=1;j<=len;j++){ int v=(i+j-1); if(v>en)v-=len; if(s[st+j-1]<s[v])break; if(s[st+j-1]>s[v])return 0; } } return 1; } int main() { int T,n; scanf("%d",&T); while(T--){ scanf("%s",s+1); int len=strlen(s+1),fla=0; for(int i=1;i<=len;){ for(int j=len;j>=i;j--){ if(check(i,j)){ if(fla==0)fla=1; else printf(" "); for(int k=i;k<=j;k++)printf("%c",s[k]); i=j+1; // cout<<i<<endl; break; } } } printf("\n"); } return 0; }