题意:判断给定串可以写成多少种二进制等式且成立的形式。
题解:利用暴力+语法分析解题。
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define Result pair<char*,int>
#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<char, int> 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);
}