poj1068

    xiaoxiao2021-04-11  40

    看题或者提交点击这里哦~

    题意:一个括号表达式可以按照如下的规则表示,就是每个右括号之前的左括号数。 比如(((()()()))),每个右括号之前的左括号数序列为P=4 5 6 6 6 6,而每个右括号所配对的左括号是距离他的第几个W=1 1 1 4 5 6. 现在给定P,输出W。

    讲解在这里~:

                 首先说哪坑吧!就在那个n值那里!n (1 <= n <= 20),n是右括号(也就是单个括号的个数)。因为我们要从数组p[]着手还原原来的括号字符串s[],所以这里的n (1 <= n <= 40);

    怎么还原?这里就用到了类似于尺取法(每个右括号前有多少个左括号=p[i]-p[i-1]);建议自己手动看看规律嘿嘿。

    然后遍历字符串,每当遇到右括号,就回溯找前面的左括号(还要判断左括号是否已配对)

    那i-j+1的差值就是与这个右括号配对的左括号的距离,因为其中已经过了已配对的括号,其中也包括已配对的右括号,所以需要(i-j+1)/2;  

    我觉得这个用的方法不是模拟法,而是构造法,因为是自己找的规律,并没有用到模拟括号配对。。。但是不明白为什么大家都说这是模拟法~

    #include<stdio.h> #include<string.h> using namespace std; int main() { char s[42]; int p[22],w[22]; int t,book[42]={0}; scanf("%d",&t); while(t--) { int n,i,j,m=0; memset(book,0,sizeof(book)); scanf("%d",&n); p[0]=0; for(i=1;i<=n;i++) { scanf("%d",&p[i]); int temp=p[i]-p[i-1]; while(temp--) { s[m++]='('; } s[m++]=')'; } /*for(i=0;i<m;i++) printf("%c",s[i]); */ int mm=1; for(i=0;i<m;i++) { if(s[i]==')') { for(j=i-1;j>=0;j--) { if(s[j]=='('&&!book[j]) { w[mm++]=(i-j+1)/2; book[j]=1; break; } } } } for(i=1;i<mm;i++) printf("%d ",w[i]); printf("\n"); } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-666758.html

    最新回复(0)