Description
给一个数字字符串,通过**,**分割使其称为单调递增字符串。
Input
输入多个字符串
Output
结果可能有多种,输出结果在分割尽量多的情况下,第一个数字尽可能大,相同则比较第二个,依次递推。
样例
3456
3546
3526
0001
100000101
0
Sample Output
3,4,5,6
35,46
3,5,26
0001
100,000101
思路:对字符串进行两次DP,第一次找出尽可能小的上升序列,使得最后一个数字达到最小。第二次,从后往前,使得第一个数字尽可能大。同时需要技巧判断两个区间的数字大小还有不要用截取直接比较,因为字典序。。。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
char a[100];
bool test(int i, int j, int x, int y)
{
int len1=j-i+1;
int len2=y-x+1;
while(a[i]=='0'&&i<=j)
{
i++;
len1--;
}
while(a[x]=='0'&&x<=y)
{
x++;
len2--;
}
if(len1>len2) return true;
else if(len1<len2) return false;
else
{
for(int k=0; k<len1; k++)
{
if(a[k+i]>a[x+k])
return true;
else if(a[k+i]<a[x+k])
return false;
}
}
return false;
}
int dp[101];
int main()
{
while(~scanf("%s",a+1))
{
int n=strlen(a+1);
if(n==1&&a[1]=='0') break;
for(int i=1; i<=n; i++)
{
dp[i]=i;
for(int j=i-1; j>=1; j--)
if(test(j+1,i,j-dp[j]+1,j))
{
dp[i]=i-j;
break;
}
}
int t=n-dp[n]+1;
dp[t]=dp[n];
for(int i=n-dp[n];i>=1;i--){
if(a[i]=='0'){
dp[i]=dp[i+1]+1;
continue;
}
for(int j=t;j>=0;j--){
if(test(j,j+dp[j]-1,i,j-1)){
dp[i]=j-i;
break;
}
}
}
int tmp=dp[1]+1;
for(int i=1;i<=n;i++){
if(tmp==i){
printf(",");
tmp=dp[i]+i;
}
printf("%c",a[i]);
}
printf("\n");
}
}