题目地址: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;
}