poj-1068

又捡了一道水题做.曾经有个大牛跟我说:成为大牛的方法是刷水题.我无意成为大牛,但是也要从水题开始刷.

poj-1068 - Parencodings

问题描述:

一组括号 (((( ) ( ) ( ) ) ) )

有两种描述方法:

P方法:4 5 6 6 6 6 - 每一个)前,有几个(

W方法:1 1 1 4 5 6 - 每一个),向前数几个是跟它匹配的(

要求是根据P求W

问题分析:

 

解题思路:

1. 虽然没说,但是可以推测出,括号的个数是偶数;第一个一定是(,最后一个一定是)

2. P方法和W方法之间可能存在公式类的规律,但是要寻找不是特别简单

3. 手动分析过程中,我们知道,可以模拟出推到W的过程-模拟法

4. 括号匹配,一定是stack结构

5. 思路就是:根据P还原括号数组,利用stack,推到出W

因为数字描述的是')',所以我们先把数组初始化成都是'('.对于第N个数p,如第一个数4,4表示这个')'前边的'('个数,如果再知道前边')'的个数,那么这个')'的下标就找到了. N就是前边')'的个数,所以stack[N+p]=')'.

怎么利用stack推倒出W呢?也很简单,遍历stack数组,当我们发现')'时候,就向前找,另w = 1,c = 0,遇到一个')'加1,同时c加1,说明中间遇到一对(),遇到一个'('减1,当w为0时候,就找到了匹配的'('. c就是个数.

AC源码:

#include <stdio.h>
#include <string.h>

#define DEBUG 0

int main( void ){
    int n_case = 0 , n_number = 0 , _n = 0 , _n_number = 0 , _c = 0 , _sp = 0 , _tmp = 9 , r = 0;
    int numbers [ 40 ] = { 0 };
    int stack [ 40 ] = { 0 };
#if DEBUG
    freopen( "data" , "r" , stdin);
#endif

    scanf( "%d" , & n_case);
    while( n_case --)
    {
        memset( numbers , 0 , sizeof( numbers));
        memset( stack , 0 , sizeof( stack));
        scanf( "%d" , & n_number);
        _n = 0;
        _n_number = n_number;

        // 1. get number and build stack
        while( n_number > 0) {
            scanf( "%d" , & numbers [ _n ]);
            stack [ numbers [ _n ] + _n ] = 1;

            ++ _n;
            -- n_number;
        }
#if DEBUG
        for ( _n = 0; _n < _n_number * 2; ++ _n) {
            printf( "%d " , stack [ _n ]);
        }
        printf( " \n ");
#endif
        // 2. retell the process of W-S
        for ( _n = 0; _n < _n_number * 2; ++ _n) {
            if ( 0 == stack [ _n ]) continue;
            _c = 1;
            r = 1;
            for ( _sp = _n - 1; _sp > 0; -- _sp) {
                if ( stack [ _sp ] == 1)
                {
                    ++ _c;
                    ++ r;
                }
                else
                    -- _c;
                if ( _c == 0)
                    break;
            }
            if ( _n == _n_number * 2 - 1)
                printf( "%d \n " , r);
            else
                printf( "%d " , r);
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/linucos/archive/2011/10/12/2208567.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值