Codeforces Gym 101158E Infallibly Crack Perplexing Cryptarithm Gym [语法分析]

题意:判断给定串可以写成多少种二进制等式且成立的形式。

题解:利用暴力+语法分析解题。

AC代码:

#include
using namespace std;
#define Result pair
#define FAIL make_pair((char*)NULL,0)
char srcExpr[32], expr[32], op[8] = {'0', '1', '+', '-', '*', '(', ')', '='};
struct Parser {
    Result Q(char* p) {
        Result res = E(p);
        if(res.first == NULL || *(res.first) != '=')    return FAIL;

        Result rgt = E(res.first+1);
        if(rgt.first == NULL || *(rgt.first) != 0 || rgt.second != res.second)  return FAIL;
        return rgt;
    }
    Result E(char *p) {
        Result ret = T(p);
        if(ret.first == NULL)   return FAIL;
        while(*(ret.first) == '+' || *(ret.first) == '-')
        {
            Result tmp = T(ret.first + 1);
            if(tmp.first == NULL)   return FAIL;
            if(*(ret.first) == '-') ret.second -= tmp.second;
            else    ret.second += tmp.second;
            ret.first = tmp.first;
        }
        return ret;
    }
    Result T(char *p) {
        Result ret = F(p);
        if(ret.first == NULL)   return FAIL;
        if(*(ret.first) == '*')
        {
            Result tmp = T(ret.first + 1);
            if(tmp.first == NULL)   return FAIL;
            ret.first = tmp.first,  ret.second *= tmp.second;
        }
        return ret;
    }
    Result F(char *p) {
        Result ret;
        if(*p == '-') {
            Result ret = F(p+1);
            ret.second = -ret.second;
            return ret;
        } else if(*p == '(') {
            Result ret = E(p+1);
            if(ret.first == NULL || *(ret.first) != ')')    return FAIL;
            ret.first++;
            return ret;
        } else {
            return N(p);
        }
    }
    Result N(char *p) {
        Result ret;
        if(!isdigit(*p))    return FAIL;
        if(*p == '0' && isdigit(*(p+1)))    return FAIL;
        while(isdigit(*p))
        {
            (ret.second *= 2) += (*p-'0');
            p++;
        }
        ret.first = p;
        return ret;
    }
};
int main()
{
    sort(op, op+8);
    scanf("%s", srcExpr);
    map mp;
    int idx = 0;
    for(int i=0;srcExpr[i];i++)
    {
        if(isalpha(srcExpr[i]) && mp.find( srcExpr[i] ) == mp.end())
            mp[ srcExpr[i] ] = ++idx;
    }

    if(idx > 8) {   printf("0\n");  return 0;   }
    int ans = 0;
    do {
        for(int i=0;srcExpr[i];i++)
            expr[i] = (isalpha(srcExpr[i]) ? op[ mp[srcExpr[i]]-1 ] : srcExpr[i]);
        if(Parser().Q(expr).first != NULL)  ans++;  
    } while(next_permutation(op, op+8));
    int factorial = 1;
    for(int i=1;i<=(8-idx);i++)
        factorial *= i;
    printf("%d\n", ans / factorial);
}


你可能感兴趣的:(Codeforces,语法分析)