[贪心]CF227C.Geoge and Number

C. George and Number
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

George is a cat, so he really likes to play. Most of all he likes to play with his array of positive integers b. During the game, George modifies the array by using special changes. Let's mark George's current array as b1, b2, ..., b|b| (record |b| denotes the current length of the array). Then one change is a sequence of actions:

  • Choose two distinct indexes i and j (1 ≤ i, j ≤ |b|; i ≠ j), such that bi ≥ bj.
  • Get number v = concat(bi, bj), where concat(x, y) is a number obtained by adding number y to the end of the decimal record of number x. For example, concat(500, 10) = 50010, concat(2, 2) = 22.
  • Add number v to the end of the array. The length of the array will increase by one.
  • Remove from the array numbers with indexes i and j. The length of the array will decrease by two, and elements of the array will become re-numbered from 1 to current length of the array.

George played for a long time with his array b and received from array b an array consisting of exactly one number p. Now George wants to know: what is the maximum number of elements array b could contain originally? Help him find this number. Note that originally the array could contain only positive integers.

Input

The first line of the input contains a single integer p (1 ≤ p < 10100000). It is guaranteed that number p doesn't contain any leading zeroes.

Output

Print an integer — the maximum number of elements array b could contain originally.

Sample test(s)
Input
9555
Output
4
Input
10000000005
Output
2
Input
800101
Output
3
Input
45
Output
1
Input
1000000000000001223300003342220044555
Output
17
Input
19992000
Output
1
Input
310200
Output
2
Note

Let's consider the test examples:

  • Originally array b can be equal to {5, 9, 5, 5}. The sequence of George's changes could have been: {5, 9, 5, 5} → {5, 5, 95} → {95, 55} → {9555}.
  • Originally array b could be equal to {1000000000, 5}. Please note that the array b cannot contain zeros.
  • Originally array b could be equal to {800, 10, 1}.
  • Originally array b could be equal to {45}. It cannot be equal to {4, 5}, because George can get only array {54} from this array in one operation.

Note that the numbers can be very large.


设某一个解集合为S,并且操作的序列为O

S是数集N的集合,O的操作限于S的元素之间。

若O1是O的一个排列,则必定存在S1是S的一个排列,是另一个解。

即答案可以取S的任意排列。即S无序。而N有序。


不妨取排列S0,S0中数字的顺序和p的数字出现的顺序相同,|S0|是答案。满足上述要求。

设集合P=(p1,p2,p3.....),定义num(S)运算,得到一个数

S0是P的一个划分。在i处划分的要求是存在i,j,num([N1...Ni]) > num(Ni+1...Nj)。


是一个动态规划问题,按照一个方向计算。但是其中隐含了一些条件没有利用。


假设已经确定上一个划分的位置,如何确定划分?如果过于靠左,可能会导致数太小。如果过于靠右,可能导致结果太小。

我们换一个方向,从后往前计算。假设已经确定下一个划分,如何确定划分?尽量靠右,可以使左边没有划分的区域“发挥的空间”更大,同时更容易满足划分的要求。因此确定了我们的贪心策略。


考虑细节问题:不允许存在N=0。因此我们从右往左,扫到一个不为零的数,则把它连同后面的零(如果有)划进一个N。因此每一个N,有且只有一个非零数字。

另一个细节问题:当不存在划分使划分左边比划分右边大时,说明这个区间不能够继续划分了。特别的,位数相同时,我们要手动判断大小。


#include <cstdio>
#include <cstring>

char num[100010];

bool bigger(int l,int m,int r)
{
	for (int i=1;i<r-m+1;i++)
		if (num[l+i-1]<num[m+i])
			return false;
	return true;
}

int main()
{
	scanf("%s",num+1);
	int n = strlen(num+1);
	int i = n; int j; int ans = 0;
	while (i >= 1)
	{
		j = i;
		while (num[j--]=='0'&&j>=1);
		if (j>i-j || (j==i-j&&bigger(1,j,i))) ans++;
		else break;
		i = j;
	}

	printf("%d",ans+1);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值