刷题记录(NC16660 [NOIP2004]FBI树,NC50999 表达式计算4)

NC16660 [NOIP2004]FBI树

题目链接

关键点

1、分治:返回左边的字符和右边的字符,如果字符相同且为‘B’,那么当前串就为‘B’,为‘T’,当前串就为‘T’,如果不同,那么当前串为‘F’,且如果当前区间左右端点相同,那么直接判断字符返回相应字符(B, T)

# include <iostream>
using namespace std;
int n;
string s;
char deal(int l, int r)
{
    if (l==r)
    {
        if (s[l]=='0')
        {
            cout<<'B';
            return 'B';
        }
        else
        {
            cout<<'I';
            return 'I';
        }
    }
    int mid = (l+r)/2;
    char left = deal(l, mid);
    char right = deal(mid+1, r);
    if (left==right)
    {
        if (left == 'I')
        {
            cout<<'I';
            return 'I';
        }
        else if (left == 'B')
        {
            cout<<'B';
            return 'B';
        }
    }
    cout<<'F';
    return 'F';
}
int main()
{
    cin>>n>>s;
    deal(0, s.size()-1);
     
     
    return 0;
}

 NC50999 表达式计算4

题目链接

关键点: 

1、分治:找在括号外第一个符号,如果为‘+’,那么两边函数相加,以此类推

2、如何处理多余括号:用一个cnt来记当前的括号(左括号+1,右括号-1),当cnt不为0,说明有多余括号,此时如果括号外无+-*/^这些符号:分为以下几种情况:

(((((1+4*5)此时左括号可以删去 

(1+4*5))))))右括号可以删去

if (cnt>0&&s[l]=='(')
    return deal(l+1, r);
if (cnt<0&&s[r]==')')
    return deal(l, r-1);

如果cnt为0

(((1+5*4)))两边均可以删去

if (cnt==0&&s[l]=='(')
   return deal(l+1, r-1);

 最后如果括号外存在运算符号,那么就可以直接利用,最后要返回转换值

完整代码:

# include <iostream>
# include <cstring>
# include <cmath>
using namespace std;
string s;
int zhuan(int l, int r)
{
    int sum = 0;
    for (int i=l; i<=r; i++)
        sum = sum*10+s[i]-'0';
    return sum;
}
int deal(int l, int r)
{
    int cnt = 0;
    int fj=-1, fc=-1, fjie=-1;
    for (int i=l; i<=r; i++)
    {
        if (s[i]=='(')
            cnt++;
        if (s[i]==')')
            cnt--;
        if (cnt==0)
        {
            if (s[i]=='+'||s[i]=='-')
            fj = i;
            if (s[i]=='*'||s[i]=='/')
                fc = i;
            if (s[i]=='^')
                fjie = i;
        }
    }
    if (fj==-1&&fc==-1&&fjie==-1)
    {
        if (cnt==0&&s[l]=='(')
            return deal(l+1, r-1);
        if (cnt>0&&s[l]=='(')
            return deal(l+1, r);
        if (cnt<0&&s[r]==')')
            return deal(l, r-1);
    }
    if (fj!=-1)
    {
        if (s[fj]=='+')
        return deal(l, fj-1)+deal(fj+1, r);
        else
        return deal(l, fj-1)-deal(fj+1, r);
    }
    else if (fc!=-1)
    {
        if (s[fc]=='*')
        return deal(l, fc-1)*deal(fc+1, r);
        else
        return deal(l, fc-1)/deal(fc+1, r);
    }
    else if (fjie!=-1)
    {
        if (s[fjie]=='^')
        return pow(deal(l, fjie-1), deal(fjie+1, r));
    }
    return zhuan(l, r);
}
int main()
{
    cin>>s;
    cout<<deal(0, s.size()-1);
    
    
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值