题目链接:
Dynamic Declaration Language (DDL) - POJ 1684 - Virtual Judge
题目大意:
给n组指令,指令有以下几种。
DCL X 表示定义一个名为X的变量,并且初值为0
INC X 变量名为X的值+1
DEC X 变量名为X的值-1
GOTO X label 如果变量X的值大于0,则跳转到第label行,反之,跳过这条指令到下一行(我就是这段读错题意了,我以为是跳到label的下一行)
GOTO label 跳转到label行
END 结束操作
X = value 将value赋值给变量X
如果定义(DCL X)了一个变量之后,没有对他进行操作(指没有INC或DEC或GOTO X或赋值)就再次定义(DCL X)则报指令为1的错误。输出为i 1(即第i行出现1错误)。
如果未定义变量,就对这个变量进行操作,则报指令为2的错误。输出为i 2(第i行出现2错误)。
以上报错行的命令均无效。
且此题有多组数据,输出答案前需要输出这是第几组数据(我不知道是我读题有问题还是怎么样,我根本没有在题目中看到这个意思,还是根据输出猜出来的)
解题思路:
其实这题不难,是一个很直白的模拟题,但是有挺多细节需要注意。
我的思路是,首先将所有命令读进来,用结构体存储。结构体的op表示这是第一个命令,t表示这个变量名是什么,val表示如果值读入(比如赋值语句和GOTO语句),则是这个值。t的初值是‘-’,其他初值是0.
开两个map<char,int>f, value,第一个用于处理DCL语句,如果x没有定义,则f[x] = 0;定义了,f[x] = 1;如果这个变量的值被处理过了,则f[x] = 2.value[x]表示x的值。
然后就按照题意进行操作就好。
这题思路不难。为数不多的难点在于正确理解题意,字符串的读入,细节处理。
不过这几点也同样是这种没有什么需要贪心思路的模拟题的注意点。
我的代码逻辑还算清晰,具体细节就不讲了,直接上代码。
代码实现:
#include <iostream>
#include <map>
using namespace std;
const int N = 2e4 + 107;
struct node {
int op;
char t;
int val;
}a[N];
map<char, int> f, value;
int main () {
ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
for (int cas = 1; cas <= T; cas++) {
cout << cas << endl;
f.clear();
value.clear();
int n;
cin >> n;
string s;
for (int i = 1; i <= n; i++) {
a[i].op = 0;
a[i].t = '-';
a[i].val = 0;
cin >> s;
if (s == "DCL") {
a[i].op = 1;
cin >> s;
a[i].t = s[0];
} else if (s == "INC") {
a[i].op = 2;
cin >> s;
a[i].t = s[0];
} else if (s == "DEC") {
a[i].op = 3;
cin >> s;
a[i].t = s[0];
} else if(s == "GOTO") {
a[i].op = 4;
cin >> s;
if (isdigit(s[0])) {
for (int j = 0; j < s.size(); j++) {
a[i].val = a[i].val * 10 + (s[j] - '0');
}
} else {
a[i].t = s[0];
cin >> s;
for (int j = 0; j < s.size(); j++) {
a[i].val = a[i].val * 10 + (s[j] - '0');
}
}
} else if (s == "END") {
a[i].op = 5;
} else {
a[i].op = 6;
a[i].t = s[0];
cin >> s;
if (s != "=") continue;
cin >> s;
for (int j = 0; j < s.size(); j++) {
a[i].val = a[i].val * 10 + (s[j] - '0');
}
}
}
int i = 1;
while (i <= n) {
if (a[i].op == 1) {//DCL f[t] = 0 DCL没操作 1 2已经操作
if (f[a[i].t] == 1) {
cout << i << " 1\n";
} else {
f[a[i].t] = 1;
value[a[i].t] = 0;
}
i++;
} else if (a[i].op == 2) {//INC
if (f[a[i].t] == 0) {
cout << i << " 2\n";
} else {
f[a[i].t] = 2;
value[a[i].t]++;
}
i++;
} else if (a[i].op == 3) {//DEC
if (f[a[i].t] == 0) {
cout << i << " 2\n";
} else {
f[a[i].t] = 2;
value[a[i].t]--;
}
i++;
} else if (a[i].op == 4) {//goto
if (a[i].t != '-') {
if (f[a[i].t] == 0) {
cout << i << " 2\n";
i++;
} else {
if (value[a[i].t] > 0) {
i = a[i].val;
} else {
i++;
}
}
} else {
i = a[i].val;
}
} else if (a[i].op == 5) {
break;
} else if (a[i].op == 6) {
if (f[a[i].t] == 0) {
cout << i << " 2\n";
} else {
f[a[i].t] = 2;
value[a[i].t] = a[i].val;
}
i++;
}
}
}
return 0;
}