1. 程式人生 > >【NOIP2011普及組T4】表示式的值-模擬+棧

【NOIP2011普及組T4】表示式的值-模擬+棧

測試地址:表示式的值

做法:一般求表示式值的問題都用棧來解決,而這一題棧中的每一個元素要存兩個數,可以用pair來儲存,first表示一段中結果為0的情況數,second表示一段中結果為1的情況數。設定一個函式f(l,r)表示[l,r]這一段所得的結果情況數(返回值形式為上述的pair),不難想到處理方法:如果l>r,返回(1,1)。由於'+'運算子優先順序最低,所以一旦找到括號外的'+'運算子,它一定是最後計算的,記下位置為i。如果找不到括號外的'+'運算子,則找括號外的'*'運算子,因為'*'運算子的優先順序僅高於'+'運算子,找到後記下位置為i。如果還找不到,則說明整個式子就由括號包括起來的,則返回f(l+1,r-1)(即把括號剝去計算裡面的值)。對於上面記下的i,可以將剩下的字元分成兩段:[l,i-1]和[i+1,r],遞迴求出f(l,i-1)和f(i+1,r),然後根據運算子的型別處理,即可算出f(l,r)。為了節省時間,我們可以在開始先掃一遍找出所有相對應的括號的位置,這樣在尋找運算子時,如果遇到括號的一部分,就可以直接跳過括號內的全部內容,因為這裡面肯定沒有我們要找的東西。

以下是本人程式碼:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define mod 10007
using namespace std;
typedef pair<int,int> pa;
char s[100010];
int l,p[100010];
stack<int> a;

pa calc(pa a,pa b,char c)
{
  pa so;
  if (c=='+')
  {
    so.first=(a.first*b.first)%mod;
	so.second=((a.first*b.second)%mod+(a.second*b.first)%mod+(a.second*b.second)%mod)%mod;
  }
  else
  {
    so.first=((a.first*b.first)%mod+(a.second*b.first)%mod+(a.first*b.second)%mod)%mod;
	so.second=(a.second*b.second)%mod;
  }
  return so;
}

pa f(int l,int r)
{
  int i;
  if (l>r) return make_pair(1,1);
  for(i=r;i>=l;i--)
  {
    if (s[i]==')') i=p[i];
	if (s[i]=='+') break;
  }
  if (i<l)
  {
    for(i=r;i>=l;i--)
    {
	  if (s[i]==')') i=p[i];
	  if (s[i]=='*') break;
	}
  }
  else
  {
    pa x,y;
	x=f(l,i-1);y=f(i+1,r);
	return calc(x,y,'+');
  }
  if (i<l) return f(l+1,r-1);
  else
  {
    pa x,y;
	x=f(l,i-1);y=f(i+1,r);
	return calc(x,y,'*');
  }
}

int main()
{
  scanf("%d",&l);
  scanf("%s",s);
  
  for(int i=l-1;i>=0;i--)
  {
    if (s[i]==')') a.push(i);
	if (s[i]=='(')
	{
	  p[a.top()]=i;
	  a.pop();
	}
  }
  
  printf("%d",f(0,l-1).first%10007);
  
  return 0;
}


相關推薦

NOIP2011普及T4表示式-模擬+

測試地址:表示式的值 做法:一般求表示式值的問題都用棧來解決,而這一題棧中的每一個元素要存兩個數,可以用pair來儲存,first表示一段中結果為0的情況數,second表示一段中結果為1的情況數。設

NOIP2013普及P2表示式(NKOJ2500)題解

【NOIP2013普及組P2】表示式求值 Time Limit:10000MS  Memory Limit:128000K Total Submit:37 Accepted:19 Case Time

NOIP2015普及T4推銷員-優先佇列

測試地址:推銷員 做法:先來分析一下題目。從題目中的樣例,我們可以得到一個猜想:後面的決策一定包含前面的決策。這個結論是可以證明的,證明過程這裡就不贅述了。因此,我們只需要分階段一步步在決策中新增住戶

NOIP2005普及T4迴圈-高精度

測試地址:迴圈 做法:兩年了!!兩年來,我數次挑戰,屢敗屢戰,屢戰屢敗,終於在今天,終於把這題AC了! 好吧迴歸主題。我們設L(k)為尾k位的迴圈節長度,不難發現L(k)=mL(k-1),其中1≤m≤

2105. NOIP2016普及複賽魔法陣

題目描述 題目分析 這一道題就是一個字首和與字尾和的問題。 如果我們已經確定了A物品和B物品,我們該怎樣知道組成ABCD四個物品的方案數呢? 我們只要求另外兩個CD點對的方案數就行了。 我們假設sum[i]為從第i個點到第n個點的CD點對方案數,那

codevs 5126[NOIP2015 普及T4]推銷員(貪心)

5126 推銷員 NOIP2015 時間限制: 1 s   空間限制: 128000 KB   題目等級 : 黃金 Gold 題目描述 Description  阿明是一名推銷員,他奉命到螺絲街推銷他

表達式的NOIP2011 普及第四題)

兩種 可能 完成 表示 請問 字符 syn http 數字0 描述 對於 1 位二進制變量定義兩種運算:運算的優先級是:1. 先計算括號內的,再計算括號外的。2. “×”運算優先於“⊕”運算,即計算表達式時,先計算×運算,再計算⊕運算。 例如:計算表達式A⊕B × C 時,

NOIP2017普及賽後心得

ora 特殊 簡單 text 很多 調試 就是 str 格子 我覺得可能今生再也見不到這麽簡單的題目了……甚至有種能AK的錯覺(不 然而考場上腦殼疼了,只剩下310~330。 T4告訴我以後遇到不會的東西一定要早點學…… 題目分析 T1 分數 這次連模擬都不用了,幹脆叫你輸

NOIP 2011 普及 T4 表達式的

字符串包含 pri 進制 字符 bits range 一個 DC 一個棧 題目 題目描述 對於1 位二進制變量定義兩種運算: 運算的優先級是: 先計算括號內的,再計算括號外的。 “× ”運算優先於“⊕”運算,即計算表達式時,先計算× 運算,再計算⊕運算。例如:計

[jzoj]2018.07.12NOIP普及模擬賽D:解題報告

1.權勢二進位制 題目: 一個十進位制整數被叫做權勢二進位制,當他的十進位制表示的時候只由0或1組成。例如0,1,101,110011都是權勢二進位制而2,12,900不是。 當給定一個n的時候,計算一下最少要多少個權勢二進位制相加才能得到n。 輸入: k組測試資料。 輸出:

[jzoj]2018.07.15NOIP普及模擬賽D:解題報告

目錄: 1.馬農 2.馬語翻譯 3.馬球比賽  4.棋盤遊戲 1.馬農 題目描述: 在觀看完戰馬檢閱之後,來自大草原的兩兄弟決心成為超級“馬農”,專門飼養戰馬。 兄弟兩回到草原,將可以養馬的區域,分為 N*N 的單位面積的正方形, 並實地進行考察,歸納出了每

NOIP2018普及對稱二叉樹

@對稱二叉樹@ @題目描述@ @題解@ @程式碼@ @[email protected] @題目描述@ 一棵有點權的有根樹如果滿足以下條件,則被軒軒稱為對稱二叉樹: 二叉樹;

NOIP2018普及擺渡車

@擺渡車@ @題目描述@ @絕對不可能是正解的題解@ @程式碼 - [email protected] @看起來比較像正解的題解@ @程式碼 - [email protected] @[email

NOIP2011提高選擇客棧

題目背景 NOIP2011提高組 DAY1 試題。 題目描述 麗江河邊有 n 家很有特色的客棧,客棧按照其位置順序從 1 到 n 編號。每家客棧都按照某一種色調進行裝飾(總共 k 種,用整數 0 ~ k-1 表示),且每家客棧都設有一家咖啡店,每家咖啡店均有各自的最低消

NOIP2016普及魔法陣的解析——一些神奇的列舉優化

題目大意:給定一個序列,要求求出滿足,且的a,b,c,d的數量. 首先這道題可以直接用一個桶,先把所有數塞進這個桶裡. 然後我們可以開始列舉答案. 但我們發現,所以我們可以省去以為的列舉,做到列舉,實測在洛谷上能拿到85分. 到這一步優化的程式碼如下: #inc

NOIP2017普及正式賽跳房子

這一題很有它的價值,我都要認真思考一番才能夠想到方法。 先講一下題目大意 題目描述 跳房子,也叫跳飛機,是一種世界性的兒童遊戲,也是中國民間傳統的體育遊戲之一。跳房子的遊戲規則如下: 在地面上確定一個起點,然後在起點右側畫 n 個格子,這些格子都在同一條

NOIP2017普及正式賽棋盤

此題依舊簡單,用一個深搜+記憶化就可以AC了! var way:array[1..4,1..2] of longint=((1,0),(0,1),(-1,0),(0,-1)); a,zx:array[0..101,0..101] of longin

NOIP2017普及正式賽 圖書管理員

這一題有很多人都搞不懂意思。但是,只要是認真看了題的人,就不會有什麼錯了! 這一題直接用暴力是可以過的,不需要wjq講的什麼字典樹(不過空閒者可“自殘”一下) var ycl:array[1..8] of longint=(10,100,1000,10000,10000

2018.10.06NOIP普及模擬賽C

T1 YY 題目描述 最近小h接到命令,要再出一份題目,於是小h馬上陷入了沉思之中,想到了yy曾經出過的一道題目:給出一個超大正整數S,S的位數小於500000,然後找出一個數 n, 使得n