POJ 1068 Parencodings (模拟)

题目地址:http://poj.org/problem?id=1068

难得的1Y,要好好纪念一下。

题目大意:有一串叫S的括号字符串,还有两个与之对应的密文规则——P-s,W-s,其规则是这个样子的

 

P-s:由一串数字组成,每个数字代表了一个右括号,而数字的大小意义为前面有多少左括号;

W-s:由一串数字组成,每个数字代表了一个右括号,而数字的大小意义为这个右括号和前面与之对应的左括号之间存在多少个成功匹配的括号对。

 

拿题目给的示例来说:

P-s中的白框4,代表这里有个右括号,而前面有4个左括号(红色下划线处)

W-s中的绿框4,代表这里有个右括号,而这个右括号与红色下划线区域第三个括号匹配,而这两个括号之间有4个匹配括号对(包括自身)。

 

题意就这么回事,题目输入P-s,要求打印W-s,我采取的方法是先把P-s转化为S,然后由S转换为W-s

由P-s转化为S很好处理,先处理记录右括号个数,然后向里面填充左括号,

有S转化为W-s也不难,利用栈,很方便就能匹配括号并统计括号对个数;

 

代码如下:

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

int ps[1000];
bool s[1000];
int ws[1000];
int z[1000];

int pd (int st,int et)   //已知括号对的起点终点,
{                       //再利用栈来统计起点到终点的括号对的个数
    int zhan[1000];       
    int ans = 1;
    int i,q = 0;
    for (i = st;i < et;i++)
        if (!s[i])
            zhan[q++] = 0;
        else if (q > 0)
        {
            q--;
            ans++;
        }
    return ans;
}

int main()
{
    int N;
    int i,k;
    scanf ("%d",&N);

    while (N--)
    {
        int n;
        scanf ("%d",&n);

        for (i = 0;i < n;i++)
            scanf ("%d",&ps[i]);

        memset(s,0,sizeof (s));

        int e = 0;

        for (i = 0;i < n;i++)         //P-s转化为S
        {
            int bj = 0;
            for (k = 0;k < e;k++)
                if (!s[k])
                    bj++;
            if (bj == ps[i])
                s[e++] = 1;
            else
            {
                for (k = 0;k < ps[i] - bj;k++)
                    s[e++] = 0;
                s[e++] = 1;
            }
        }
        int st = 0;
        int ps = 0;
        memset (z,0,sizeof (z));

        for (i = 0;i < e;i++)        //S转化为W-s
        {
            if (!s[i])
                z[st++] = i;        //记录下左括号的位置,以便调用函数的时候作为起点
            else
                ws[ps++] = pd (z[--st],i);
        }

        for (i = 0;i < n;i++)
        {
            printf ("%d",ws[i]);
            if (i < n - 1)
                printf (" ");
            else
                printf ("\n");
        }
    }

    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值