SGU 182 Open the brackets(构造)

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=182

题意:给定一个表达式,可能有几种运算(可能带括号),让你求一个不带括号的等价表达式。

运算符                   对应C++中的操作符

!(取反)                           !

||(或)                            ||

&(与)                            &&

<=>(相等)                        ==

=>(包含)                      <=(小于等于)

#                                ^(异或)

对于符号的优先级:() > ! > & > 其他。对于其他运算符,优先级相等,也就是遵循从左到右的运算法则。

思路:字母出现最多10种,暴力枚举每种的取值。对于每一种,结果为0忽视;结果为1,取值为1的直接与(&),取值为0的与非(&!)。想问题要注意转换角度。

#include <iostream>

#include <cstdio>

#include <string.h>

#include <algorithm>

#include <cmath>

#include <vector>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <map>





#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))

#define abs(x) ((x)>=0?(x):-(x))

#define i64 long long

#define u32 unsigned int

#define u64 unsigned long long

#define clr(x,y) memset(x,y,sizeof(x))

#define CLR(x) x.clear()

#define ph(x) push(x)

#define pb(x) push_back(x)

#define Len(x) x.length()

#define SZ(x) x.size()

#define PI acos(-1.0)

#define sqr(x) ((x)*(x))



#define FOR0(i,x) for(i=0;i<x;i++)

#define FOR1(i,x) for(i=1;i<=x;i++)

#define FOR(i,a,b) for(i=a;i<=b;i++)

#define DOW0(i,x) for(i=x;i>=0;i--)

#define DOW1(i,x) for(i=x;i>=1;i--)

#define DOW(i,a,b) for(i=a;i>=b;i--)

using namespace std;





void RD(int &x){scanf("%d",&x);}

void RD(i64 &x){scanf("%I64d",&x);}

void RD(u32 &x){scanf("%u",&x);}

void RD(double &x){scanf("%lf",&x);}

void RD(int &x,int &y){scanf("%d%d",&x,&y);}

void RD(i64 &x,i64 &y){scanf("%I64d%I64d",&x,&y);}

void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);}

void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}

void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}

void RD(i64 &x,i64 &y,i64 &z){scanf("%I64d%I64d%I64d",&x,&y,&z);}

void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);}

void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}

void RD(char &x){x=getchar();}

void RD(char *s){scanf("%s",s);}

void RD(string &s){cin>>s;}



void PR(int x) {printf("%d\n",x);}

void PR(i64 x) {printf("%I64d\n",x);}

void PR(u32 x) {printf("%u\n",x);}

void PR(double x) {printf("%.4lf\n",x);}

void PR(char x) {printf("%c\n",x);}

void PR(char *x) {printf("%s\n",x);}

void PR(string x) {cout<<x<<endl;}





bool Q[7][7]={

    {0,1,1,1,1,1,0},

    {0,1,1,1,1,1,0},

    {0,0,1,1,1,1,0},

    {0,0,1,1,1,1,0},

    {0,0,1,1,1,1,0},

    {0,0,1,1,1,1,0},

    {1,1,1,1,1,1,1}};

string a,b;

int p[15],q[15];

stack<int> num,op;





void pop()

{

    int t=op.top(),x,y;

    op.pop();

    if(t==0)

    {

        x=num.top();num.pop();

        num.push(!x);

    }

    else

    {

        y=num.top();num.pop();

        x=num.top();num.pop();

        if(t==1) x=x&y;

        else if(t==2) x=x||y;

        else if(t==3) x=!(x&&!y);

        else if(t==4) x=(x==y);

        else if(t==5) x=x^y;

        num.push(x);

    }

}



void cal()

{

    while(!num.empty()) num.pop();

    while(!op.empty()) op.pop();

    int i,t;

    for(i=0;i<b.length();i++)

    {

        if(b[i]>='a'&&b[i]<='j') num.push(q[b[i]-'a']);

        else if(b[i]==')')

        {

            while(op.top()!=6) pop();

            op.pop();

        }

        else

        {

            t=b[i]-'0';

            while(!op.empty()&&op.top()!=6&&Q[op.top()][t])

                 pop();

            op.push(t);

        }

    }

    while(!op.empty()) pop();

    if(!num.top()) return;

    if(a.length()>0) a+="||";

    int flag=0;

    for(i=0;i<10;i++) if(p[i])

    {

        if(flag) a+='&';

        if(q[i]==1) a+=(i+'a');

        else a+='!',a+=(i+'a');

        flag=1;

    }

}



void DFS(int dep)

{

    if(dep==10)

    {

        cal();

        return;

    }

    if(!p[dep])

    {

        DFS(dep+1);

        return;

    }

    q[dep]=1; DFS(dep+1);

    q[dep]=0; DFS(dep+1);

}



void deal()

{

    a="";

    DFS(0);

    int i;

    if(a.length()>0) cout<<a<<endl;

    else

    {

        for(i=0;i<10;i++) if(p[i])

        {

            printf("%c&!%c\n",i+'a',i+'a');

            return;

        }

    }

}



int main()

{

    cin>>a;

    b="";

    int i;

    for(i=0;i<a.length();i++)

    {

        if(a[i]>='a'&&a[i]<='j') b+=a[i],p[a[i]-'a']=1;

        else if(a[i]=='!') b+='0';

        else if(a[i]=='&') b+='1';

        else if(a[i]=='|')

        {

            b+='2';

            i++;

        }

        else if(a[i]=='=')

        {

            b+='3';

            i++;

        }

        else if(a[i]=='<')

        {

            b+='4';

            i+=2;

        }

        else if(a[i]=='#') b+='5';

        else if(a[i]=='(') b+='6';

        else if(a[i]==')') b+=a[i];

    }

    deal();

    return 0;

}

  

 

你可能感兴趣的:(rack)