P1310 表達式的值

P1310 表達式的值

題解html

 

1.假設有兩個布爾變量 x , y c++

   x0表示使得x=0的方案數spa

   x1表示使得x=1的方案數code

   y0表示使得y=0的方案數htm

   y1表示使得y=1的方案數blog

| 按位或 & 按位與
 0 0 -> 0   0 0 -> 0 
 0 1 -> 1  0 1 -> 0
 1 0 -> 1  1 0 -> 0
 1 1 -> 1  1 1 -> 1


then, get

x | y=0  方案數爲 x0*y0string

x | y=1  方案數爲 x0*y1+x1*y0+x1*y1it

x & y=0  方案數爲  x0*y1+x1*y0+x0*y0  table

x & y=1  方案數爲  x1*y1

 

 

2.中綴轉後綴規則

考慮用棧維護。

遍歷中綴表達式:

  1. 遇到數字,直接放入答案序列

  2. 遇到左括號,入棧

  3. 遇到右括號,把棧頂到上一個左括號的元素依次出棧並放入答案序列
  4. 遇到乘號,入棧
  5. 遇到加號,從棧頂開始彈出這段連續的乘號,並放入答案序列,最後加號入棧
  6. 最後把棧裏剩下的元素依次放入答案序列

 

 

 

代碼

#include<bits/stdc++.h>

using namespace std;

const int mod=1e4+7;
const int maxn=1e5+5;
int n;
char zhong[maxn];  //輸入的中序遍歷 
stack<char>sta;    //
string hou;        //轉化的後綴表達式 
stack<int> zero,one;  //答案爲0的方案數,答案爲1的方案數 

int main()
{
    scanf("%d",&n);
    scanf("%s",zhong+1);  //下標從1開始 
    
    hou.push_back('n');   //後綴表達式裏一開始要有一個未知數 
    
    //中綴轉後綴 
    for(int i=1;i<=n;i++)
    {
        if(zhong[i]=='('||zhong[i]=='*')
           sta.push(zhong[i]);
        if(zhong[i]=='+')
        {
            while(!sta.empty()&&sta.top()=='*')
            {
                hou.push_back(sta.top());
                sta.pop(); 
            }
            sta.push(zhong[i]);
        }   
        if(zhong[i]==')')
        {
            while(sta.top()!='(')
            {
                hou.push_back(sta.top());
                sta.pop(); 
            }
            sta.pop();  //彈出'(' 
        }
        if(zhong[i]!='('&&zhong[i]!=')')
          hou.push_back('n');  //放入一個未知變量 
    } 
    
    //棧裏面剩餘的存入後綴 
    while(!sta.empty())
    {
        hou.push_back(sta.top());
        sta.pop(); 
    }
    
    //遍歷後綴 
    for(int i=0;i<hou.size() ;i++)
    {
        char c=hou[i];
        
        if(c=='n')
        {
            zero.push(1);
            one.push(1);
        }
        else
        {
            int rone=one.top(),rzero=zero.top();
            one.pop();
            zero.pop();
            //rone->y1 , rzero->y0
            
            int lone=one.top(),lzero=zero.top();
            one.pop();
            zero.pop();
            //lone->x1 , lzero->x0
            
            if(c=='*')  
            {
                one.push(lone*rone%mod);
                zero.push((lone*rzero%mod+lzero*rone%mod+lzero*rzero%mod)%mod);
            }
            else
            {
                one.push((lone*rone%mod+lone*rzero%mod+lzero*rone%mod)%mod);
                zero.push(lzero*rzero%mod);
            }
        }
    }
    
    printf("%d",zero.top());  //輸出答案 
    
    return 0;
}

 

 

 

Thanks

water-lift

相關文章
相關標籤/搜索