http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3683
很恶心的模拟。。。
很久之前做的了。。。发下代码,供后来人对拍,找错。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<map>
using namespace std;
const int SET_VAR_NUM = 1;
const int ADD_VAR_VAR = 2;
const int ADD_NUM_NUM = 3;
const int ADD_NUM_VAR = 4;
const int ADD_VAR_NUM = 5;
const int SUB_VAR_VAR = 6;
const int SUB_NUM_NUM = 7;
const int SUB_VAR_NUM = 8;
const int SUB_NUM_VAR = 9;
const int MUL_NUM_NUM = 10;
const int MUL_VAR_VAR = 11;
const int MUL_NUM_VAR = 12;
const int MUL_VAR_NUM = 13;
const int DIV_VAR_VAR = 14;
const int DIV_NUM_NUM = 15;
const int DIV_NUM_VAR = 16;
const int DIV_VAR_NUM = 17;
const int MOD_VAR_VAR = 18;
const int MOD_NUM_NUM = 19;
const int MOD_NUM_VAR = 20;
const int MOD_VAR_NUM = 21;
const int SETTAG = 22;
const int GOTO = 23;
const int IF_VAR = 24;
const int IF_NUM = 25;
const int PRINT_NUM = 26;
const int ADD = 27;
const int MUL = 28;
const int DIV = 29;
const int MOD = 30;
const int SET_VAR_VAR = 31;
const int PRINT_VAR = 32;
int var[1024];
int instruction[1000000][4];
map<int,int>tagnum_to_line;
int tagnum_top;
map<string,int>tag_to_tagnum;
int top;
char str[10010];
char temp[10010];
char op[10010];
char op1[10010];
char op2[10010];
char op3[10010];
int vop1,vop2,vop3;
int get_var_value(char* s){
int len=strlen(s);
int base=10;
if(s[len-1]=='D'||s[len-1]=='d')base=-10;
else if(s[len-1]=='B'||s[len-1]=='b')base=2;
else if(s[len-1]=='H'||s[len-1]=='h')base=16;
else base=10;
int res=0;
if(base==10){
for(int i=1;i<len;i++){
res=res*10+s[i]-'0';
}
}else if(base==2){
for(int i=1;i<len-1;i++){
res=res*2+s[i]-'0';
}
}else if(base==16){
for(int i=1;i<len-1;i++){
if(s[i]>='0'&&s[i]<='9'){
res=res*16+s[i]-'0';
}else if(s[i]>='a'&&s[i]<='z'){
res=res*16+s[i]-'a'+10;
}else{
res=res*16+s[i]-'A'+10;
}
}
}else{
for(int i=1;i<len-1;i++){
res=res*10+s[i]-'0';
}
}
return res;
}
int get_num_value(char* s){
int len=strlen(s);
int base=10;
if(s[len-1]=='D'||s[len-1]=='d')base=-10;
else if(s[len-1]=='B'||s[len-1]=='b')base=2;
else if(s[len-1]=='H'||s[len-1]=='h')base=16;
else base=10;
int res=0;
if(s[0]=='-'){
if(base==10){
for(int i=1;i<len;i++){
res=res*10+s[i]-'0';
}
}else if(base==2){
for(int i=1;i<len-1;i++){
res=res*2+s[i]-'0';
}
}else if(base==16){
for(int i=1;i<len-1;i++){
if(s[i]>='0'&&s[i]<='9'){
res=res*16+s[i]-'0';
}else if(s[i]>='a'&&s[i]<='z'){
res=res*16+s[i]-'a'+10;
}else{
res=res*16+s[i]-'A'+10;
}
}
}else{
for(int i=1;i<len-1;i++){
res=res*10+s[i]-'0';
}
}
return -res;
}
if(base==10){
for(int i=0;i<len;i++){
res=res*10+s[i]-'0';
}
}else if(base==2){
for(int i=0;i<len-1;i++){
res=res*2+s[i]-'0';
}
}else if(base==16){
for(int i=0;i<len-1;i++){
if(s[i]>='0'&&s[i]<='9'){
res=res*16+s[i]-'0';
}else if(s[i]>='a'&&s[i]<='z'){
res=res*16+s[i]-'a'+10;
}else{
res=res*16+s[i]-'A'+10;
}
}
}else{
for(int i=0;i<len-1;i++){
res=res*10+s[i]-'0';
}
}
return res;
}
void tran_instruction(){
int len=strlen(temp);
memset(op,0,sizeof(op));
memset(op1,0,sizeof(op1));
memset(op2,0,sizeof(op2));
memset(op3,0,sizeof(op3));
sscanf(temp,"%s",op);
if(strcmp(op,"SET")==0){
sscanf(temp,"%s %s %s",op,op1,op2);
if(op2[0]=='$'){
instruction[top][0]=SET_VAR_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
}else{
instruction[top][0]=SET_VAR_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
}
top++;
}else if(strcmp(op,"ADD")==0){
sscanf(temp,"%s %s %s %s",op,op1,op2,op3);
if(op2[0]=='$'&&op3[0]=='$'){
instruction[top][0]=ADD_VAR_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_var_value(op3);
}else if(op2[0]!='$'&&op3[0]!='$'){
instruction[top][0]=ADD_NUM_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_num_value(op3);
}else if(op2[0]=='$'&&op3[0]!='$'){
instruction[top][0]=ADD_VAR_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_num_value(op3);
}else{
instruction[top][0]=ADD_NUM_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_var_value(op3);
}
top++;
}else if(strcmp(op,"SUB")==0){
sscanf(temp,"%s %s %s %s",op,op1,op2,op3);
if(op2[0]=='$'&&op3[0]=='$'){
instruction[top][0]=SUB_VAR_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_var_value(op3);
}else if(op2[0]!='$'&&op3[0]!='$'){
instruction[top][0]=SUB_NUM_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_num_value(op3);
}else if(op2[0]=='$'&&op3[0]!='$'){
instruction[top][0]=SUB_VAR_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_num_value(op3);
}else{
instruction[top][0]=SUB_NUM_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_var_value(op3);
}
top++;
}else if(strcmp(op,"MUL")==0){
sscanf(temp,"%s %s %s %s",op,op1,op2,op3);
if(op2[0]=='$'&&op3[0]=='$'){
instruction[top][0]=MUL_VAR_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_var_value(op3);
}else if(op2[0]!='$'&&op3[0]!='$'){
instruction[top][0]=MUL_NUM_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_num_value(op3);
}else if(op2[0]=='$'&&op3[0]!='$'){
instruction[top][0]=MUL_VAR_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_num_value(op3);
}else{
instruction[top][0]=MUL_NUM_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_var_value(op3);
}
top++;
}else if(strcmp(op,"DIV")==0){
sscanf(temp,"%s %s %s %s",op,op1,op2,op3);
if(op2[0]=='$'&&op3[0]=='$'){
instruction[top][0]=DIV_VAR_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_var_value(op3);
}else if(op2[0]!='$'&&op3[0]!='$'){
instruction[top][0]=DIV_NUM_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_num_value(op3);
}else if(op2[0]=='$'&&op3[0]!='$'){
instruction[top][0]=DIV_VAR_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_num_value(op3);
}else{
instruction[top][0]=DIV_NUM_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_var_value(op3);
}
top++;
}else if(strcmp(op,"MOD")==0){
sscanf(temp,"%s %s %s %s",op,op1,op2,op3);
if(op2[0]=='$'&&op3[0]=='$'){
instruction[top][0]=MOD_VAR_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_var_value(op3);
}else if(op2[0]!='$'&&op3[0]!='$'){
instruction[top][0]=MOD_NUM_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_num_value(op3);
}else if(op2[0]=='$'&&op3[0]!='$'){
instruction[top][0]=MOD_VAR_NUM;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_var_value(op2);
instruction[top][3]=get_num_value(op3);
}else{
instruction[top][0]=MOD_NUM_VAR;
instruction[top][1]=get_var_value(op1);
instruction[top][2]=get_num_value(op2);
instruction[top][3]=get_var_value(op3);
}
top++;
}else if(strcmp(op,"SETTAG")==0){
sscanf(temp,"%s %s",op,op1);
string tag=op1;
if(tag_to_tagnum.count(tag)==0)tag_to_tagnum[tag]=tagnum_top++;
int tag_num=tag_to_tagnum[op1];
tagnum_to_line[tag_num]=top;
instruction[top][0]=SETTAG;
top++;
}else if(strcmp(op,"GOTO")==0){
sscanf(temp,"%s %s",op,op1);
string tag=op1;
if(tag_to_tagnum.count(tag)==0)tag_to_tagnum[tag]=tagnum_top++;
instruction[top][0]=GOTO;
instruction[top][1]=tag_to_tagnum[tag];
top++;
}else if(strcmp(op,"IF")==0){
sscanf(temp,"%s %s %s %s",op,op1,op2,op3);
if(op1[0]=='$'){
instruction[top][0]=IF_VAR;
instruction[top][1]=get_var_value(op1);
string tag2=op2;
if(tag_to_tagnum.count(tag2)==0)tag_to_tagnum[tag2]=tagnum_top++;
instruction[top][2]=tag_to_tagnum[tag2];
string tag3=op3;
if(tag_to_tagnum.count(tag3)==0)tag_to_tagnum[tag3]=tagnum_top++;
instruction[top][3]=tag_to_tagnum[tag3];
}else{
instruction[top][0]=IF_NUM;
instruction[top][1]=get_num_value(op1);
string tag2=op2;
if(tag_to_tagnum.count(tag2)==0)tag_to_tagnum[tag2]=tagnum_top++;
instruction[top][2]=tag_to_tagnum[tag2];
string tag3=op3;
if(tag_to_tagnum.count(tag3)==0)tag_to_tagnum[tag3]=tagnum_top++;
instruction[top][3]=tag_to_tagnum[tag3];
}
top++;
}else if(strcmp(op,"PRINT")==0){
sscanf(temp,"%s %s",op,op1);
if(op1[0]=='$'){
instruction[top][0]=PRINT_VAR;
instruction[top][1]=get_var_value(op1);
}else{
instruction[top][0]=PRINT_NUM;
instruction[top][1]=get_num_value(op1);
}
top++;
}
}
void analyse(){
int len=strlen(str);
memset(temp,0,sizeof(temp));
int t=0;
for(int i=0;i<len;i++){
if(str[i]=='#'){
tran_instruction();
t=0;
memset(temp,0,sizeof(temp));
return;
}else if(str[i]==';'){
tran_instruction();
t=0;
memset(temp,0,sizeof(temp));
}
else temp[t++]=str[i];
}
if(t>0)tran_instruction();
}
void run(){
int now=1;
int now_op;
int now_op1;
int now_op2;
int now_op3;
while(now<top){
now_op=instruction[now][0];
now_op1=instruction[now][1];
now_op2=instruction[now][2];
now_op3=instruction[now][3];
var[0]=0;
if(now_op==SET_VAR_NUM){
var[now_op1]=now_op2;
}else
if(now_op==SET_VAR_VAR){
var[now_op1]=var[now_op2];
}else
if(now_op==ADD_NUM_NUM){
var[now_op1]=now_op2+now_op3;
}else
if(now_op==ADD_NUM_VAR){
var[now_op1]=now_op2+var[now_op3];
}else
if(now_op==ADD_VAR_NUM){
var[now_op1]=var[now_op2]+now_op3;
}else
if(now_op==ADD_VAR_VAR){
var[now_op1]=var[now_op2]+var[now_op3];
}else
if(now_op==SUB_NUM_NUM){
var[now_op1]=now_op2-now_op3;
}else
if(now_op==SUB_NUM_VAR){
var[now_op1]=now_op2-var[now_op3];
}else
if(now_op==SUB_VAR_NUM){
var[now_op1]=var[now_op2]-now_op3;
}else
if(now_op==SUB_VAR_VAR){
var[now_op1]=var[now_op2]-var[now_op3];
}else
if(now_op==MUL_NUM_NUM){
var[now_op1]=now_op2*now_op3;
}else
if(now_op==MUL_NUM_VAR){
var[now_op1]=now_op2*var[now_op3];
}else
if(now_op==MUL_VAR_NUM){
var[now_op1]=var[now_op2]*now_op3;
}else
if(now_op==MUL_VAR_VAR){
var[now_op1]=var[now_op2]*var[now_op3];
}else
if(now_op==DIV_NUM_NUM){
var[now_op1]=now_op2/now_op3;
}else
if(now_op==DIV_NUM_VAR){
var[now_op1]=now_op2/var[now_op3];
}else
if(now_op==DIV_VAR_NUM){
var[now_op1]=var[now_op2]/now_op3;
}else
if(now_op==DIV_VAR_VAR){
var[now_op1]=var[now_op2]/var[now_op3];
}else
if(now_op==MOD_NUM_NUM){
var[now_op1]=now_op2%now_op3;
}else
if(now_op==MOD_NUM_VAR){
var[now_op1]=now_op2%var[now_op3];
}else
if(now_op==MOD_VAR_NUM){
var[now_op1]=var[now_op2]%now_op3;
}else
if(now_op==MOD_VAR_VAR){
var[now_op1]=var[now_op2]%var[now_op3];
}else
if(now_op==SETTAG){
//DO NOTHING
}else
if(now_op==GOTO){
now=tagnum_to_line[now_op1];
}else
if(now_op==IF_NUM){
if(op1>0){
now=tagnum_to_line[now_op2];
}else{
now=tagnum_to_line[now_op3];
}
}else
if(now_op==IF_VAR){
if(var[now_op1]>0){
now=tagnum_to_line[now_op2];
}else{
now=tagnum_to_line[now_op3];
}
}else
if(now_op==PRINT_NUM){
printf("%d\n",now_op1);
}else
if(now_op==PRINT_VAR){
printf("%d\n",var[now_op1]);
}
var[0]=0;
now++;
}
}
void init(){
top=1;
tagnum_top=1;
tagnum_to_line.clear();
tag_to_tagnum.clear();
memset(var,0,sizeof(var));
memset(instruction,0,sizeof(instruction));
memset(temp,0,sizeof(temp));
}
int main(){
int n;
while(~scanf("%d\n",&n)){
init();
for(int i=0;i<n;i++){
gets(str);
analyse();
}
run();
printf("\n");
}
}