蓝桥杯历届试题:兰顿蚂蚁 java实现
题:
兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。
平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。
蚂蚁的头部朝向为:上下左右其中一方。
蚂蚁的移动规则十分简单:
若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;
若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。
规则虽然简单,蚂蚁的行为却十分复杂。刚刚开始时留下的路线都会有接近对称,像是会重复,但不论起始状态如何,蚂蚁经过漫长的混乱活动后,会开辟出一条规则的“高速公路”。
蚂蚁的路线是很难事先预测的。
你的任务是根据初始状态,用计算机模拟兰顿蚂蚁在第n步行走后所处的位置。
输入格式
输入数据的第一行是 m n 两个整数(3 < m, n < 100),表示正方形格子的行数和列数。
接下来是 m 行数据。
每行数据为 n 个被空格分开的数字。0 表示白格,1 表示黑格。
接下来是一行数据:x y s k, 其中x y为整数,表示蚂蚁所在行号和列号(行号从上到下增长,列号从左到右增长,都是从0开始编号)。s 是一个大写字母,表示蚂蚁头的朝向,我们约定:上下左右分别用:UDLR表示。k 表示蚂蚁走的步数。
输出格式
输出数据为两个空格分开的整数 p q, 分别表示蚂蚁在k步后,所处格子的行号和列号。
以下是输入输出
刚开始做这个题感觉非常容易,但是当我开始写代码的时候就遇到了一点小问题,最后一行输入的方向字符楞是没法取到,最后问了一下度娘才解决hiahiahia~
直接上代码:
import java.util.Scanner;
// 历届试题 兰顿蚂蚁
public class Main {
//创建静态流,实现输入
static Scanner in = new Scanner(System.in);
static int m = in.nextInt();
static int n = in.nextInt();
static int arr[][] = new int[m][n];
public static void main(String[] args) {
//输入黑白格
for(int i = 0;i < m;i++) {
for(int j = 0; j < n;j++) {
arr[i][j] = in.nextInt();
}
}
//完成最后行输入
int x = in.nextInt();
int y = in.nextInt();
char s = in.next().charAt(0);
int k = in.nextInt();
//生成蚂蚁对象
PointForAnt ant = new PointForAnt(x,y,s);
//蚂蚁执行运动
for(int i = 0;i < k;i++) {
ant.move(ant, arr);
}
//输出蚂蚁位置
System.out.println(ant.getX()+" "+ant.getY());
in.close();
}
}
//蚂蚁类
class PointForAnt{
private int x;
private int y;
private char s;
//构造方法
public PointForAnt(int x,int y,char s) {
this.setX(x);
this.setY(y);
this.setS(s);
}
//getter and setter
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public char getS() {
return s;
}
public void setS(char s) {
this.s = s;
}
//向左转向方法
public void getTurnRight() {
if(this.s == 'U') {
this.s = 'R';
}else if(this.s == 'R') {
this.s = 'D';
}else if(this.s == 'D') {
this.s = 'L';
}else {
this.s = 'U';
}
}
//向右转向方法
public void getTurnLeft() {
//判断头朝向,并执行不同的变化
if(this.s == 'U') {
this.s = 'L';
}else if(this.s == 'L') {
this.s = 'D';
}else if(this.s == 'D') {
this.s = 'R';
}else {
this.s = 'U';
}
}
//move方法
public void move(PointForAnt ant,int arr[][]) {
//根据蚂蚁头朝向执行不同操作
if(ant.getS() == 'U') {
//移动
if(arr[ant.getX()][ant.getY()] == 0) {
ant.getTurnLeft();
arr[ant.getX()][ant.getY()] = 1;
ant.setY(y-1);
}else {
ant.getTurnRight();
arr[ant.getX()][ant.getY()] = 0;
ant.setY(y+1);
}
}else if(ant.getS() == 'D') {
//移动
if(arr[ant.getX()][ant.getY()] == 0) {
ant.getTurnLeft();
arr[ant.getX()][ant.getY()] = 1;
ant.setY(y+1);
}else {
ant.getTurnRight();
arr[ant.getX()][ant.getY()] = 0;
ant.setY(y-1);
}
}else if(ant.getS() == 'L') {
//移动
if(arr[ant.getX()][ant.getY()] == 0) {
ant.getTurnLeft();
arr[ant.getX()][ant.getY()] = 1;
ant.setX(x+1);
}else {
ant.getTurnRight();
arr[ant.getX()][ant.getY()] = 0;
ant.setX(x-1);
}
}else {
//移动
if(arr[ant.getX()][ant.getY()] == 0) {
ant.getTurnLeft();
arr[ant.getX()][ant.getY()] = 1;
ant.setX(x-1);
}else {
ant.getTurnRight();
arr[ant.getX()][ant.getY()] = 0;
ant.setX(x+1);
}
}
}
}
可以看到我是使用这一行代码获取输入的第一个字符,并且它也不影响之后键盘输入数值的接受。
char s = in.next().charAt(0);
题目中需要输入的东西挺多,但其实仔细一读,如果把蚂蚁的行为和与矩阵关联的事件进行分步,利用函数来一步一步完成它的实现,那就会相当有利于面向对象思维的培养。