NOIP2005 等價表示式

2021-07-10 20:51:03 字數 3119 閱讀 1805

等價表示式

(equal.pas/c/cpp)

【問題描述】

明明進了中學之後,學到了代數表示式。有一天,他碰到乙個很麻煩的選擇題。這個題目的題幹中首先給出了乙個代數表示式,然後列出了若干選項,每個選項也是乙個代數表示式,題目的要求是判斷選項中哪些代數表示式是和題幹中的表示式等價的。

這個題目手算很麻煩,因為明明對計算機程式設計很感興趣,所以他想是不是可以用計算機來解決這個問題。假設你是明明,能完成這個任務嗎?

這個選擇題中的每個表示式都滿足下面的性質:

1. 表示式只可能包含乙個變數『a』。

2. 表示式中出現的數都是正整數,而且都小於10000。

3. 表示式中可以包括四種運算『+』(加),『-』(減),『*』(乘),『^』(乘冪),以及小括號『(』,『)』。小括號的優先順序最高,其次是『^』,然後是『*』,最後是『+』和『-』。『+』和『-』的優先順序是相同的。相同優先順序的運算從左到右進行。(注意:運算子『+』,『-』,『*』,『^』以及小括號『(』,『)』都是英文本元)

4. 冪指數只可能是1到10之間的正整數(包括1和10)。

5. 表示式內部,頭部或者尾部都可能有一些多餘的空格。

下面是一些合理的表示式的例子:

((a^1) ^ 2)^3,a*a+a-a,((a+a)),9999+(a-a)*a,1 + (a -1)^3,1^10^9……

【輸入檔案】

輸入檔案equal.in的第一行給出的是題幹中的表示式。第二行是乙個整數n(2 <= n <= 26),表示選項的個數。後面n行,每行包括乙個選項中的表示式。這n個選項的標號分別是a,b,c,d……

輸入中的表示式的長度都不超過50個字元,而且保證選項中總有表示式和題幹中的表示式是等價的。

【輸出檔案】

輸出檔案equal.out包括一行,這一行包括一系列選項的標號,表示哪些選項是和題幹中的表示式等價的。選項的標號按照字母順序排列,而且之間沒有空格。

【樣例輸入】

( a + 1) ^2

3(a-1)^2+4*a

a + 1+ a

a^2 + 2 * a * 1 + 1^2 + 10 -10 +a -a

【樣例輸出】

ac【資料規模】

對於30%的資料,表示式中只可能出現兩種運算子『+』和『-』;

對於其它的資料,四種運算子『+』,『-』,『*』,『^』在表示式中都可能出現。

對於全部的資料,表示式中都可能出現小括號『(』和『)』。

【思路】

帶值判斷+計算表示式。

本題的關鍵在於計算表示式的值,大體過程就是利用兩個棧分別儲存運算數和運算子。維護運算子棧中運算子的優先順序總是由頂到下遞減的。

遇到數字的時候將數讀完存入opint,遇到a的時候換為值存入opint

遇到運算子c的時候:如果opchar棧頂優先順序比c小則將c存入opchar,如果相等則取出棧頂,如果棧頂的優先順序更大則計算。

輸入點中有個不滿足正確性的表示式為 ()) 的形式,需要特殊處理一下。

還有乙個點需要提到:題目中的資料如果有long long存的話任然會溢位,但並不需要因此加入高精計算,因為只是判斷兩個式子的結果是否相等,如果相等的話就算是溢位的結果也是相等的。

詳見**。

【**】

1 #include 2 #include 3 #include 4 #include 5 #include 6

using

namespace

std;

78 typedef long

long

ll;9

const

int maxn = 120+10;10

11char

str[maxn], s1[maxn],s2[maxn];

12int nei[maxn*3], wai[maxn*3

];13 ll t[10] = ;

14 stackopchar;

15 stackopint;

16bool

flag;

1718 ll calculate(ll x, ll y, char

c)1930}

31char cmp(char a, char

b)32

38 ll solve(char *s, ll t)

3952

opint.push(num);53}

54else

if(s[i] == 'a'

)5559else

6072 ll ta =opint.top();

73opint.pop();

74if

(opint.empty())

7578 ll tb =opint.top();

79opint.pop();

80 ll s=calculate(tb, ta, opchar.top());

81opint.push(s);

82//

cout<83

opchar.pop();

84break;85

}86}87

}88return

opint.top();89}

90void

init()

9196

intmain()

97136

//cout<137

}138

if(flag) printf("

%c", i + 'a'

);139

}140 printf("\n"

);141

return0;

142 }

NOIP 2005 等價表示式

題目描述 明明進了中學之後,學到了代數表示式。有一天,他碰到乙個很麻煩的選擇題。這個題目的題幹中首先給出了乙個代數表示式,然後列出了若干選項,每個選項也是乙個代數表示式,題目的要求是判斷選項中哪些代數表示式是和題幹中的表示式等價的。這個題目手算很麻煩,因為明明對計算機程式設計很感興趣,所以他想是不是...

NOIP2005 等價表示式

明明進了中學之後,學到了代數表示式。有一天,他碰到乙個很麻煩的選擇題。這個題目的題幹中首先給出了乙個代數表示式,然後列出了若干選項,每個選項也是乙個代數表示式,題目的要求是判斷選項中哪些代數表示式是和題幹中的表示式等價的。這個題目手算很麻煩,因為明明對計算機程式設計很感興趣,所以他想是不是可以用計算...

NOIP 2005 等價表示式 題解

昨天覆習了一下表示式 棧 和圖論相關的演算法,結果卡在一道題上,上午做的等價表示式,下午才有所進展,最後好不容易寫出來了個像樣的程式,但又因為落谷和codevs上資料有誤 左右括號不匹配導致r re,例如 a 2 2 折騰半天,最後到vijos上也只是分多了點,也沒a掉。兩個棧是肯定的,乙個用來儲存...