1. 程式人生 > >NOI.AC #53. eval

NOI.AC #53. eval


題目描述
或許這道題比經典的“表示式求值”還是要簡單一點的。

有一種簡單的程式語言,我們如下定義其中的概念:

常數:單個數字,即 0 到 9。注意不會出現多位數字的情況。
變數:單個大寫字母,即 A 到 Z。每個變數可以儲存一個整數,所有變數的初始值為 0。
值:常數或者變數。
賦值語句:由變數、=、值構成,例如 A=3,B=A,C=C。表示將變數修改為右側的值。
加法語句:由變數、+=、值構成,例如 A+=9,B+=B。表示將變數額外加上右側的值。
語句:賦值語句、加法語句或者迴圈語句。
迴圈語句:由 for(、變數、,、值、,、值、)、語句構成,例如 for(I,0,9)A+=I,for(I,0,9)for(J,0,I)A+=J。設兩個值在此時依次為 aa 和 bb,則:
所有的輸入資料保證此時 a≤ba≤b。
依次令變數取 a,a+1,a+2,…,ba,a+1,a+2,…,b,計算右側的語句。
整個迴圈語句結束後,變數的值取 bb。
右側的語句中,保證不會對迴圈變數進行修改(即不會出現在賦值語句和加法語句的左側,也不會成為另一個迴圈語句的變數),並且如果 aa 和 bb 是變數,也不會對其進行修改。
輸入格式
從標準輸入讀入資料。

輸入若干行,每行包含一個語句。你需要從上到下依次執行這些語句。

不會出現空格等無關字元。

輸出格式
輸出到標準輸出。

按照字母的順序,輸出所有不為 0 的變數。每行輸出一個,格式為:變數名、=、它的值。如果值的位數超過了 9 位,則只輸出其最後 9 位,並在之前新增 …。

樣例
輸入
for(I,0,9)A+=I
for(I,0,9)for(J,0,I)B+=J
C=1
for(I,1,3)for(J,0,9)C+=C
輸出
A=45
B=165
C=…073741824
I=3
J=9


模擬題就要模擬到底,寫結構體加過載運算子之類的保證正確性。
AC Code:

#include<cstdio>
#include<cctype>
#define mod 1000000000

struct num{int a,b;}a[30];
inline num calc(char c){ if(isdigit(c)) return num{c-'0',0};return a[c-'A']; }
inline num add(num a,num b){ return num{(a.a+b.a)%mod,a.b|b.b|(a.a+b.a>=mod)}; }
char s[105];
inline void dfs(int now)
{
	if(s[now] == 'f')
	{
		for(a[s[now+4]-'A']=calc(s[now+6]);;a[s[now+4]-'A']=add(a[s[now+4]-'A'],num{1,0}))
		{
			dfs(now+10);
			if(a[s[now+4]-'A'].a==calc(s[now+8]).a) return;
		}
	}
	else 
		if(s[now+1]=='+') a[s[now]-'A'] = add(a[s[now]-'A'],calc(s[now+3]));
		else a[s[now]-'A'] = calc(s[now+2]);
}

int main()
{
	for(;scanf("%s",s)!=EOF;) 
		dfs(0);
	for(int i=0;i<26;i++) 
		if(a[i].a || a[i].b){
			if(a[i].b) printf("%c=...%09d\n",i+'A',a[i].a);
			else printf("%c=%d\n",i+'A',a[i].a);
		}
}