[Codeforces 7E] Defining Macros

Link:http://codeforces.com/problemset/problem/7/E

 

Brief Introduction:一个表达式由多个“Macros”组成,每个Macro都为一个整体,如果最终的表达式使得运算顺序发生改变则称该表达式不安全

                            给你多个Macros和最终的表达式,询问该表达式是否安全

 

Algorithm:

要判断最终的表达式是否安全,就是要看其中的每个Macro是否安全,同时每一个运算符是否会使其整个变得不安全

我们发现要判断每个Macro的安全性也要经过同样的过程

从而将原问题化归为了解决多个相同的子问题并最终加合的问题。这样就可以想到利用递归或dp来解决问题

 

我们可以将每一部分划为4个状态,方便之后状态的加合

0:本身已经不安全

1:该macro在“/”或"-"后不安全

2:该macro仅在"/"后不安全

3:无论何时此皆安全

 

这样就构建了状态“安全程度”的单调性。判断两表达式加合起来的状态时,仅要判断其是否大于某个安全程度即可

 

Code:

#include <bits/stdc++.h>

using namespace std;

int n,len=0,w=0;
string t;
char s[200];
map<string,int> mp;

int eval(int l,int r)
{
    for(int i=r,w=0;i>l;i--)
        if(w+=(s[i]==')'),w-=(s[i]=='('),!w&&(s[i]=='-' || s[i]=='+'))
        {
            int L=eval(l,i-1),R=eval(i+1,r);
            return L&&R&&(s[i]!='-' || R>1); //对"-"后的判断为安全程度是否大于1
        }
    for(int i=r,w=0;i>l;i--)
        if(w+=(s[i]==')'),w-=(s[i]=='('),!w&&(s[i]=='*' || s[i]=='/'))
        {
            int L=eval(l,i-1),R=eval(i+1,r);
            return (L>1)&&(R>1)&&(s[i]!='/' || R>2)?2:0;
        }
    if(s[l]=='(') //有了括号,就没有1、2状态了
        return eval(l+1,r-1)?3:0;
    string a(s+l,s+r+1);
    return mp.count(a)?mp[a]:3;
}

int Get()
{
    gets(s);
    for(int i=len=0;s[i];i++)
        if(s[i]!=' ') s[len++]=s[i];
    return eval(0,len-1);
}

int main()
{
    cin >> n;
    for(int i=1;i<=n;i++)
    {
        scanf(" #%*s");cin >> t;
        mp[t]=Get();
    }
    cout << (Get()?"OK":"Suspicious");
    return 0;
}

 

Review:

1、字符串读入技巧:

scanf中*s,*d均为省略符号,只读取而不存储

使用gets函数可读取这一行剩下的所有内容

 

2、对此类包含括号匹配问题的通用技巧:

在循环时用一个变量记录此时括号是否已经匹配,是则进行递归

 

3、当发现可以将问题变为更小规模分别处理时,使用递归手法,正确将状态分类

 

4、如果状态种类较多,可以构建状态从“好”到“坏”的单调性从而方便判断

posted @ 2018-05-10 17:12  NewErA  阅读(544)  评论(0编辑  收藏  举报