NOI.AC #53. eval

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/83539224

题目描述
或许这道题比经典的“表达式求值”还是要简单一点的。

有一种简单的编程语言,我们如下定义其中的概念:

常数:单个数字,即 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);
		}
}

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/83539224