hdu 4964 Emmet(模拟)

题意:根据要求翻译html代码……

思路:不是很难的模拟,但是写的有点晚,比赛结束后5分钟过掉了,真是忧伤。。。这个题处理好两个东西就好了,一个是*%d,另一个是(),剩下的就好搞了。首先确定一下大体思路,整个html代码的最外层的标签一定在最前面,那么也就是从前向后处理,先不管前面提到要处理的两个东西,首先提取最外层的标签,得到头(head)和尾(end),递归处理剩下的内容(context),那么结果就等于 head + context + end。对于*%d的情况,先得到需要重复的次数,得到*1的内容以后,将这个结果复制n次就行了。对于(),题中给出了()一定在最后,所以需要考虑的就变少了。首先要找一个合法的括号序列,那么可以这样处理,定义一个sum,初值为0,遇到(,sum++,遇到),sum--,这样,当sum等于0的时候,就说明遇到了一个合法的序列,递归处理(因为可能存在嵌套),由于每个合法序列是并列的,将得到的结果依次连接在一起就行了。


代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn = 1000+10;
string str,S[maxn];
int cnt,n;
struct Node
{
    string head,end,context;
    void Uion(Node a)
    {
        context = a.head + a.context + a.end;
    }
};
Node cal(int L,int R)
{
    string name = "",id = "",cls = "";
    int s = L;
    while(s <=R && str[s] != '.' && str[s] != '#')
        name += str[s++];
    while(s <= R)
    {
        if(str[s] == '.')
        {
            s++;
            if(cls.length()) cls += " ";
            while(s <= R && str[s] != '.' && str[s] != '#')
                cls += str[s++];
        }
        else
        {
            s++;
            while(s <= R && str[s] != '.' && str[s] != '#')
                id += str[s++];
        }
    }
    Node res;
    res.head = "<" + name;
    if(id.length()) res.head += " id=\"" + id + "\"";
    if(cls.length()) res.head += " class=\"" + cls + "\"";
    res.head += ">";
    res.end = "</" + name + ">";
    return res;
}
int getmul(int L,int R,int & r)
{
    int mul = 1;
    for(int i = L;i <= R; ++i)
    {
        if(str[i] == '*')
        {
            mul = 0;
            for(int j = i + 1;j <= R; ++j)
                mul = mul*10 + str[j] - '0';
            r = i - 1;
        }
    }
    return mul;
}
Node getStr(int L,int R)
{
    Node res,node;
    if(L > R) return res;
    if(str[L] != '(')
    {
        int mul = 1,r = L;
        while(r <= R && str[r] != '>') r++;
        r--;
        mul = getmul(L,r,r);
        res = cal(L,r);
        while(r <= R && str[r] != '>') r++;
        node = getStr(r + 1,R);
        res.Uion(node);
        for(int i = 1;i < mul ;++i)
        {
            res.context += res.end + res.head + node.head +node.context +node.end;
        }
    }
    else
    {
        int sum = 0,last = L;
        string tmp = "";
        for(int i = L;i <= R;++i)
        {
            if(str[i] == '(') sum++;
            else if(str[i] == ')') sum--;
            if(sum == 0)
            {
                node = getStr(last + 1,i-1);
                last = i + 1;
                if(res.head.length() == 0)
                    res = node;
                else
                {
                    res.context += res.end + node.head + node.context;
                    res.end = node.end;
                }
            }
        }
    }
    return res;
}
int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int t;
    cin>>t;
    while(t--)
    {
        cin>>str;
        n = str.length();
        cnt = 0;
        Node ans = getStr(0,n-1);
        cout<<ans.head<<ans.context<<ans.end<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值