• 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
    ");
    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
    ", 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
  • 相关阅读:
    [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
    自定义控件1_切换按钮
    View Animation 视图动画全解
    从图库中选取图片设置给ImageView
    一张图认识安卓shape属性
    自定义Dialog(QQ头像选择弹出的对话框)
    Toolbar和menu使用
    LIB和DLL的区别与使用
    C++调用webservice
    夯实Java基础系列5:Java文件和Java包结构
  • 原文地址:https://www.cnblogs.com/jostree/p/4020792.html
Copyright © 2020-2023  润新知