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;
}