URAL-1101. Robot in the Field
2017-09-07 22:06
344 查看
1、知识点:动态规划
2、思路:此题最大的难点恐怕还是表达式处理,我用的是栈,代码比较长,但注释比较详细。
2、思路:此题最大的难点恐怕还是表达式处理,我用的是栈,代码比较长,但注释比较详细。
/* */ #include <stdio.h> #include <string.h> #include <string> #include <stack> using namespace std; #define MAXN 100+10 //N,M,K最大值 #define MAXEXPRELEN 250+10 struct Point{ //点 int x; int y; int dir; //标记到当前点的方向 }; Point fork_point[MAXN]; //分叉点 Point cur_poi; //当前点 struct Invert{ //定义转换点 int a; int b; char c[5]; }; Invert inv[MAXN]; //转换点 char sent[MAXEXPRELEN]; //表达式 int reg_arr[26+5]; //寄存器数组 int N, //field M, //fork K; //register-invert-point int get_val(const char *formu); //计算表达式的值 int get_pri(string str); //获取优先级 bool is_fork(); //判断当前点是否分叉 void next_posi(int res, Point &poi); //根据当前点计算下一个位置 bool is_out(Point poi); //检查新点是否出界 bool is_invert(int ®); //检查当前点是否转换点,若是可得寄存器编号 int main() { memset(reg_arr, 0, sizeof(reg_arr)); gets(sent); scanf("%d%d%d", &N, &M, &K); for(int i=0; i<M; i++) scanf("%d%d", &(fork_point[i].x), &(fork_point[i].y)); for(int j=0; j<K; j++) scanf("%d%d%s", &(inv[j].a), &(inv[j].b), &(inv[j].c)); cur_poi.x = 1; cur_poi.y = 0; cur_poi.dir = 1; //(0,0)->(1,0):右 printf("%d %d\n", 0, 0); printf("%d %d\n", 1, 0); Point new_poi; int inv_reg; //转换的寄存器编号 for(;;){ int res = -1; //默认直走 if(is_fork()) //如果站在分叉点 res = get_val(sent); //左,右? if(is_invert(inv_reg)) //如果站在转换点 reg_arr[inv_reg] = 1 - reg_arr[inv_reg]; next_posi(res, new_poi); //计算下一个点 bool ch = is_out(new_poi); //检查新点是否出界 if(!ch){ printf("%d %d\n", new_poi.x, new_poi.y); cur_poi.x = new_poi.x; cur_poi.y = new_poi.y; cur_poi.dir = new_poi.dir; } else break; } return 0; } int get_val(const char *formu) { string expre = formu; expre += "#"; int len = expre.length(); stack<string> sym; stack<string> oper; string str=""; //临时字符串 string top_str=""; //栈顶运算符 string top_oper=""; //栈顶操作数 int str_len=0; sym.push("#"); for(int i=0; i<len; i++){ str += expre[i]; str_len++; if(str == " "){ //如果是空格 str = ""; str_len = 0; continue; } if(isalpha(str[0])){ int j; for(j=i+1; j<len; j++) if(isalpha(expre[j])){ str += expre[j]; str_len++; } else break; i = j-1; //其它字符,i移至最后一个有效字符 } if( str=="TRUE" || str=="FALSE" || (isalpha(str[0]) && str_len == 1)) //寄存器或真值 oper.push(str); else{ //操作符 或 括号 if(get_pri(str) > get_pri(sym.top()) || (sym.top()=="("&&str!=")") || str=="NOT")//>栈顶优先级 或 栈顶是左括号 或 "NOT"(NOT是右结合) sym.push(str); else if(sym.top()=="(" && str==")") sym.pop(); else{ //<栈顶优先级 或 右括号 或 "#" while(sym.top()!="#" && get_pri(str)<=get_pri(sym.top()) && sym.top()!="("){ bool res = 0; //临时结果 string res_str = ""; //临时结果的字符串形式(TRUE,FALSE) top_str = sym.top(); //弹出栈顶运算符 sym.pop(); top_oper = oper.top(); //弹出第一个操作数 oper.pop(); if(top_str == "NOT"){ //单操作数 (只有NOT一个) if(top_oper == "TRUE") res = 0; else if(top_oper == "FALSE") res = 1; else res = 1 - reg_arr[top_oper[0] - 'A']; } else{ //双操作数 string sec_oper = oper.top(); //第二个操作数 oper.pop(); if(top_str == "AND"){ //AND if(top_oper == "TRUE"){ if(sec_oper == "TRUE") res = 1; else if(sec_oper == "FALSE") res = 0; else res = reg_arr[sec_oper[0] - 'A']; } else if(top_oper == "FALSE") res = 0; else{ //第一个操作数是寄存器 if(!reg_arr[top_oper[0] - 'A']) res = 0; else{ if(sec_oper == "TRUE") res = 1; else if(sec_oper == "FALSE") res = 0; else res = reg_arr[sec_oper[0] - 'A']; } } } else{ //OR if(top_oper == "TRUE") res = 1; else if(top_oper == "FALSE"){ if(sec_oper == "TRUE") res = 1; else if(sec_oper == "FALSE") res = 0; else res = reg_arr[sec_oper[0] - 'A']; } else{ //第一个操作数是寄存器 if(reg_arr[top_oper[0] - 'A']) res = 1; else{ //第一个操作数为0 if(sec_oper == "TRUE") res = 1; else if(sec_oper == "FALSE") res = 0; else res = reg_arr[sec_oper[0] - 'A']; } } } } if(res == 1) res_str = "TRUE"; //运算结果转换为字符串压栈 else res_str = "FALSE"; oper.push(res_str); if(str==")" && sym.top()=="("){ //遇到左括号退出循环 sym.pop(); break; } } if(str != ")") sym.push(str); //str入栈 } } str = ""; str_len = 0; } if(!oper.empty()){ string lst = oper.top(); if(lst == "TRUE") return 1; else if(lst == "FALSE") return 0; else return reg_arr[lst[0] - 'A']; } else{ printf("oper stack is empty!"); return false; } } int get_pri(string str) { int num = 6; string prim[num] = {"#", ")", "OR", "AND", "NOT", "("}; for(int i=0; i<num; i++) if(prim[i] == str) return i; return -1; } bool is_fork() //判断当前点是否分叉 { for(int i=0; i<M; i++) if(cur_poi.x == fork_point[i].x && cur_poi.y == fork_point[i].y) return true; return false; } void next_posi(int res, Point &poi) //计算下一个位置 { int dir = cur_poi.dir; //到当前点的方向 if(res == 1){ //右拐 if(dir == 0){ //原左 poi.x = cur_poi.x; poi.y = cur_poi.y+1; poi.dir = 2; } else if(dir == 1){ //原右 poi.x = cur_poi.x; poi.y = cur_poi.y-1; poi.dir = 3; } else if(dir == 2){ //原上 poi.x = cur_poi.x+1; poi.y = cur_poi.y; poi.dir = 1; } else{ //原下 poi.x = cur_poi.x-1; poi.y = cur_poi.y; poi.dir = 0; } } else if(res == 0){ //左拐 if(dir == 0){ poi.x = cur_poi.x; poi.y = cur_poi.y-1; poi.dir= 3; } else if(dir == 1){ poi.x = cur_poi.x; poi.y = cur_poi.y+1; poi.dir = 2; } else if(dir == 2){ poi.x = cur_poi.x-1; poi.y = cur_poi.y; poi.dir = 0; } else{ poi.x = cur_poi.x+1; poi.y = cur_poi.y; poi.dir = 1; } } else{ //直走 if(dir == 0){ poi.x = cur_poi.x-1; poi.y = cur_poi.y; } else if(dir == 1){ poi.x = cur_poi.x+1; poi.y = cur_poi.y; } else if(dir == 2){ poi.x = cur_poi.x; poi.y = cur_poi.y+1; } else{ poi.x = cur_poi.x; poi.y = cur_poi.y-1; } poi.dir = dir; } } bool is_out(Point poi) //检查(x,y)是否出界 { if(poi.x<-N || poi.x>N || poi.y<-N || poi.y>N) return true; else return false; } bool is_invert(int ®) //检查当前点是否转换点,若是,引用带回寄存器编号 { for(int i=0; i<K; i++) if(cur_poi.x == inv[i].a && cur_poi.y == inv[i].b){ reg = inv[i].c[0] - 'A'; return true; } return false; }
相关文章推荐
- ural 1101(Robot in the Field )表达式求值
- URAL - 1145 Rope in the Labyrinth
- How To Use The New Multivalue Field In Access 2007/2010 Sunday, June 19th, 2011
- For the payment term field in the order
- URAL 1145—— Rope in the Labyrinth——————【求树的直径】
- important, influential, topical or otherwise interesting paper in the field of CS every weekday
- ural 1348. Goat in the Garden 2
- Ural 1084|Goat in the Gardon|计算几何
- 百度LBS云搜索时报错 "filter:area is not filteable field, please set property in the cloud-storage
- limit_choices_to a value on a field in the same model - Google Groups
- Tips to Survive and Progress in the Field of Software Testing
- 10 types of programmers you’ll encounter in the field
- MAC OpenSSL: OpenSSL CA Signing Error field needed to be the same in the CA certificate
- GYM 100694 I.Goat in the Field(水~)
- 解题报告:Codeforces Round #226 (Div. 2)E. Bear in the Field 矩阵加速幂
- ural 1084. Goat in the Garden
- 14.64.2 表查询 Filter table by the text in a TextField
- URAL 1348. Goat in the Garden 2[求点到线段的距离]
- How to distinguish a human and a robot in the future?
- Codeforeces Round #226 (Div. 2) E---Bear in the Field(矩阵快速幂)