URAL-1101. Robot in the Field
来源:互联网 发布:乐华电视软件下载 编辑:程序博客网 时间:2024/06/05 19:34
1、知识点:动态规划
2、思路:此题最大的难点恐怕还是表达式处理,我用的是栈,代码比较长,但注释比较详细。
/**/#include <stdio.h>#include <string.h>#include <string>#include <stack>using namespace std;#define MAXN 100+10 //N,M,K最大值 #define MAXEXPRELEN 250+10struct 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-pointint 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; }
阅读全文
0 0
- URAL-1101. Robot in the Field
- ural 1101(Robot in the Field )表达式求值
- Bear in the Field CodeForces
- UVa10102 - The path in the colored field
- ural 1084. Goat in the Garden
- ural 1348. Goat in the Garden 2
- ural 1084 Goat in the Garden
- Goat in the Garden (ural 1348)
- Ural 1090. In the Army Now
- Ural 1090. In the Army Now
- ural 1090. In the Army Now
- ural 1804 The Machinegunners in a Playoff
- URAL 1090. In the Army Now
- URAL - 1145 Rope in the Labyrinth
- ural 1084. Goat in the Garden math
- The top conference in computer field
- Inverses in the Field GF(2^8)
- CodeForces 385E Bear in the Field
- Java Jedis操作Redis示例(二)——list 生产者/消费者模式实现消息队列
- pintos项目的makefile解析(一)
- Android客户端与服务器交互中的token
- 深度搜索DFS-Lake Counting(POJ NO.2386)
- java JDK&变量&运算符与表达式
- URAL-1101. Robot in the Field
- java多线程--几个多线程面试题小结
- 基于NHibernate的开发框架的设计
- Cereal library--快速入门
- java中使用SAX读取和写出XML文件
- 写一个function,清除字符串前后的空格。(兼容所有浏览器)
- 计算机网络概述(四)
- lucene入门
- win10与ubuntu16.04双系统时间不同步问题的分析与解决