zoj 3829 Known Notation

作者:jostree 转载请说明出处 http://www.cnblogs.com/jostree/p/4020792.html

题目链接: zoj 3829 Known Notation  

使用贪心+模拟。由于没有数字之间没有空格,因此该题有如下性质:

1.如果该字符串全部为数字,则无需操作,直接输出0。

2.连续的n个数字后面接连续的m个*,当n>m时,一定是有效的答案。从而最终的目的就是把最后的数字尽量向前移动,把最前面非法的*尽量向后移动,因此insert操作添加数字时,只需添加在最前面即可。

3.*的个数一定要小于数字的个数,因为每个*号需要消耗掉一个数字,并且首个*消耗掉2个数字。因此如果发现数字的个数比*的个数少k个,那么需要直接在字符串首添加k+1个数字。

4.如果字符串非全数字,那么结尾的数字一定要被替换成*,否则串无效。因此遇到第一个*时,直接与结尾的数字交换。

5.遍历整个串,当发现*的个数大于等于数字的个数时,直接把该位置的*与最后的数字进行替换。

代码如下:

 1 #include <cstdio>

 2 #include <cstdlib>

 3 #include <iostream>

 4 #include <cstring>

 5 using namespace std;

 6 char str[1010];

 7 void solve()

 8 {

 9     int len = strlen(str);

10     int nnum = 0, nstar = 0;

11     int pnum = len-1;

12     int res = 0;

13     int leftnum = 0;

14     for( int i = 0 ; i < len ; i++ )

15     {

16         if( str[i] == '*' ) nstar++;

17         else nnum++;

18     }

19     if( nnum == len )

20     {

21         printf("0\n");

22         return;

23     }

24     if( nnum - nstar <= 0)

25     {

26         leftnum = nstar -nnum + 1;

27         res +=  leftnum;

28     }

29     for( int i = 0 ; i < len ; i++ )

30     {

31         while( i < pnum && str[pnum] == '*') pnum--;

32         if( str[i] == '*' )

33         {

34             leftnum--;    

35             if( pnum == len-1 && str[pnum] != '*' )

36             {

37                 str[i] = str[pnum];

38                 str[pnum] = '*';

39                 leftnum += 2;

40                 res++;

41                 pnum--;

42             }

43             else if( leftnum <= 0 )

44             {

45                 str[i] = str[pnum];

46                 str[pnum] = '*';

47                 res++;

48                 leftnum += 2;

49             }

50         }

51         else leftnum++;

52     }

53     printf ( "%d\n", res );

54 }

55 int main(int argc, char *argv[])

56 {

57     int T;

58     scanf("%d", &T);

59     while( T-- )

60     { 

61         scanf ( "%s", str );

62         solve();

63     }

64 }
View Code

另附测试用例:

1***1

**1

1*1*1*

1*1*1*1

1**

1111*

1111*1

111**1

*111*

**1111*

***111111*

*1**1

*1**1*

*1111**

*1111**1

*111**11

***111

***

**1

*1*

*11

1*

*1

1**



3

3

1

1

2

0

1

1

1

2

2

3

3

1

1

1

3

4

3

2

1

1

2

2
View Code

 

你可能感兴趣的:(ZOJ)