CodeForces - 508E Arthur and Brackets

又来丢人现眼了。。。

一开始用递归想要枚举所有情况,没想到test 7就挂了,还没有找到原因。。。

错误代码:

//J
#include<stdio.h>
#include<string.h>
#define MAXN 610

int L[MAXN],R[MAXN];
bool vis[2*MAXN];
int ans[2*MAXN];//1代表左括号,2代表右括号
int n;
bool flag;

void dfs(int x,int pre)//x是左边的括号的序号,pre是上一个左括号的位置
{
    int i,j;

    if(x==n+1)
    {
        flag=true;
        return;
    }
    while(vis[++pre]);
    if(pre+1==')')
    {
        flag=false;
        return;
    }
    vis[pre]=1;
    ans[pre]=1;
    for(j=L[x];j<=R[x];j++)
    {
        i=pre+j;
        if(!vis[i])
        {
            vis[i]=true;
            ans[i]=2;
            dfs(x+1,pre);
            if(flag==false)
            {
                vis[i]=false;
                ans[i]=0;
            }
            else
                break;
        }
        else
        {
            ans[pre]=0;
            vis[pre]=false;
            return;
        }
    }
}

int main()
{
    int i;

    while(scanf("%d",&n)!=EOF)
    {
        memset(L,0,sizeof(L));
        memset(R,0,sizeof(R));
        for(i=1;i<=n;i++)
            scanf("%d%d",&L[i],&R[i]);
        memset(vis,0,sizeof(vis));
        memset(ans,0,sizeof(ans));
        flag=false;
        dfs(1,0);
        if(flag==true)
        {
            for(i=1;i<=2*n;i++)
            {
                if(ans[i]==0)
                {
                    flag=false;
                    break;
                }
            }
        }
        if(flag)
        {
            for(i=1;i<=2*n;i++)
            {
                if(ans[i]==1)
                    printf("%c",'(');
                else if(ans[i]==2)
                    printf("%c",')');
            }
            printf("\n");
        }
        else
            printf("%s\n","IMPOSSIBLE");
    }
    return 0;
}

 

后来看了网上大神的代码才知道,

参考博客:

https://blog.csdn.net/tc_to_top/article/details/43340685

https://blog.csdn.net/qq_24451605/article/details/47731165

 

代码中有相应的注释

代码:

//J
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
#define MAXN 610

int L[MAXN],R[MAXN];
int pos[MAXN];//放左括号的位置(分别与左括号的序号对应起来了)
char ans[2*MAXN];

stack<int>s;//存放的是左括号的序号而不是字符,因为栈中肯定全部是‘(’,所以没必要记字符

int main()
{
    int i;
    int n;
    int len;//字符串的长度
    int id;//记录当前栈顶的左括号的序号
    bool flag;

    while(scanf("%d",&n)!=EOF)
    {
        memset(pos,0,sizeof(pos));
        memset(L,0,sizeof(L));
        memset(R,0,sizeof(R));
        memset(ans,0,sizeof(ans));
        len=0;
        while(!s.empty())
            s.pop();
        flag=true;
        for(i=1;i<=n;i++)//处理左括号的顺序
        {
            scanf("%d%d",&L[i],&R[i]);
            pos[i]=len;
            ans[len++]='(';//将左括号压栈
            s.push(i);
            while(!s.empty())
            {
                id=s.top();
                if(len<pos[id]+L[id])//此时应该继续将左括号压栈
                    break;
                else if(len<=pos[id]+R[id])
                {
                    ans[len++]=')';
                    s.pop();
                }
                else
                {
                    flag=false;
                    break;
                }
            }
        }
        if(flag==true&&s.empty())//栈空表明已经匹配完成了,否则表示不能完美匹配
        {
            for(i=0;i<len;i++)
                printf("%c",ans[i]);
            printf("\n");
        }
        else
            printf("%s\n","IMPOSSIBLE");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值