日期:2014-05-20  浏览次数:20725 次

“蓝桥杯”决赛题3

【编程题】(满分18分)

  某少年宫引进了一批机器人小车。可以接受预先输入的指令,按指令行动。小车的基本动作很简单,只有3种:左转(记为L),右转(记为R),向前走若干厘米(直接记数字)。

  例如,我们可以对小车输入如下的指令:

  15L10R5LRR10R20

  则,小车先直行15厘米,左转,再走10厘米,再右转,...

  不难看出,对于此指令串,小车又回到了出发地。

  你的任务是:编写程序,由用户输入指令,程序输出每条指令执行后小车位置与指令执行前小车位置的直线距离。

【输入、输出格式要求】

  用户先输入一个整数n(n<100),表示接下来将有n条指令。

  接下来输入n条指令。每条指令只由L、R和数字组成(数字是0~100之间的整数)

  每条指令的长度不超过256个字符。

  程序则输出n行结果。

  每条结果表示小车执行相应的指令前后位置的直线距离。要求四舍五入到小数后2位。

  例如:用户输入:
5
L100R50R10
3LLL5RR4L12
LL
100R
5L5L5L5

  则程序输出:
102.96
9.06
0.00
100.00
0.00


【注意】

  请仔细调试!您的程序只有能运行出正确结果的时候才有机会得分!
   
  请把所有类写在同一个文件中,调试好后,存入与【考生文件夹】下对应题号的“解答.txt”中即可。
   
  相关的工程文件不要拷入。
   
  请不要使用package语句。
   
  源程序中只能出现JDK1.5中允许的语法或调用。不能使用1.6或更高版本。 







------解决方案--------------------
package ban.com;

import java.text.DecimalFormat;
import java.util.Scanner;

public class test {
public static int direction ;
public static int X[]={1,0,-1,0};
public static int Y[]={0,-1,0,1};
public static int x,y;
public static void GetDirection(String d){
if (d.equals("L")){
direction = (direction +1)%4;
}else if (d.equals("R")){
direction = (direction +3)%4;
}

}
public static void CountXY(int d){
x += X[direction]*d;
y += Y[direction]*d;
}
public static void getAnswer(String s){
int i,j,k;
String ss = "";
k = s.length();
for(i = 0;i<k;i++){
char c = s.charAt(i);
if (c >= '0' && c <= '9'){
ss += c;
}else {
if (!ss.equals("")){
CountXY(Integer.valueOf(ss));
ss = "";
}
GetDirection(c+"");
}
}
if (!ss.equals("")){
CountXY(Integer.valueOf(ss));
ss = "";
}

}
public static void main(String[] args) {
String s;
int n;
Scanner sc = new Scanner(System.in);
DecimalFormat dg=new DecimalFormat("0.00"); //保留两位小数
n = sc.nextInt();
while( n > 0){
direction = 0;
x = 0;
y = 0;
s = sc.next();
getAnswer(s);
System.out.println(dg.format(Math.sqrt(x*x+y*y)));
n --;
}
}
}

------解决方案--------------------
这道题没难度啊
Java code
public class MovingProcessor {
    //所谓四面八方,把方向控制好就行了
    //以2维坐标为参考,前为上(y坐标增加),右为右(x坐标增加),后为下(y坐标减少),左为左(x坐标减少)
    private static final int[][] MOVING_DIR = {{0,1}, {1,0}, {0,-1}, {-1,0}};

    protected int dir  = 0; //用于控制方向
    protected double x = 0; //用于控制x坐标
    protected double y = 0; //用于控制y坐标
    private boolean isolating = true; //是否是独立的命令(用于扩展,此题可忽略),因为是每次独立计算距离(即后面的距离不累加前面的距离),所以本题设为独立命令
    //private boolean realTime = false;//是否是实时处理(用于扩展,此题忽略)

    public MovingProcessor() {}
    public MovingProcessor(boolean isolating) {
        this.isolating = isolating; 
    }

    public void reset() { //处理器重置
        dir = 0;
        x   = 0;
        y   = 0; 
    }

    public double execute(String cmd) throws Exception { //执行指令,支持小数距离(题目给的是整数距离,这里扩展支持小数距离)
        if (isolating) reset();

        int dec = 0; //小数标志
        double num = 0, times = 0;
        for (char c : cmd.toCharArray()) { //按字符遍历指令
            if (c == 'L') { //遇到左转L指令
                if (num > 0) {//判断是否L指令前是否存在移动距离,如果存在,则先移动
                    move(num); //移动距离
                    num = 0; 
                    dec = 0;
                }
                changeDir(c); //改变方向
            } else if (c == 'R') { //遇到R右转指令
                if (num > 0) {
                    move(num);
                    num = 0;
                    dec = 0;
                }
                changeDir(c);
            } else if (c>='0' && c<='9') { //遇到数字累加数字
                if (dec == 0) { //无小数的时候
                    num = num*10 + (c-'0');
                } else { //有小数的时候
                    num += (c-'0')/times;
                    times *= 10;
                }
            } else if (c == '.') { //遇到小数点
                if (dec > 0) { //非法小数点则抛出异常
                    throw new Exception(String.format("Error Command[%s].", cmd));
                }
                dec = 1;
                times = 10;
            } else { //非法字符则抛出异常
                throw new Exception(String.format("Error Command[%s].", cmd));
            }
        }

        if (num > 0) { //如果有移动距离就移动
            move(num);
        }

        return Math.sqrt(x*x + y*y); //返回移动的距离
    }

    protected void changeDir(char dir) { //改变方向
        this.dir += (dir=='L' ? -1 : (dir=='R' ? 1 : 0));
    }

    protected void move(double value) { //移动距离
        dir %= 4;
        dir += (dir < 0) ? 4 : 0;
        x += value * MOVING_DIR[dir][0];
        y += value * MOVING_DIR[dir][1];
    }

    public static void main(String[] args) {
        String[] cmds = getCmds();
        MovingProcessor mp = new MovingProcessor();
        System.out.println("Execute Result:");
        for (String cmd : cmds) {
            try {
                System.out.printf("%.2f\n", mp.execute(cmd));
            } catch (Throwable e) {
                e.printStackTrace();
                //break; //skip, ignore, cancel, so on...
            }
        }
    }

    public static String[] getCmds() {
        String[] cmds;
        int count = 0;
        Scanner sc = new Scanner(System.in);
        try {
            System.out.println("User Input:");
            count = Integer.valueOf(sc.nextLine()).intValue();
        } catch (Throwable e) {
            e.printStackTrace();
            System.exit(-1);
        }

        cmds = new String[count];
        for (count=0; count<cmds.length; count++) {
            cmds[count] = sc.nextLine();
        }

        return cmds;
    }
}