您的位置:首页 > 编程语言 > Java开发

蓝桥杯第7届javaA决赛第3题

2017-12-31 16:54 323 查看

蓝桥杯第7届javaA决赛第3题

题目

棋子换位

有n个棋子A,n个棋子B,在棋盘上排成一行。

它们中间隔着一个空位,用“.”表示,比如:

AAA.BBB

现在需要所有的A棋子和B棋子交换位置。

移动棋子的规则是:

1. A棋子只能往右边移动,B棋子只能往左边移动。

2. 每个棋子可以移动到相邻的空位。

3. 每个棋子可以跳过相异的一个棋子落入空位(A跳过B或者B跳过A)。

AAA.BBB 可以走法:

移动A ==> AA.ABBB

移动B ==> AAAB.BB

跳走的例子:

AA.ABBB ==> AABA.BB

以下的程序完成了AB换位的功能,请仔细阅读分析源码,填写划线部分缺失的内容。

public class Main

{

    static void move(char[] data, int from, int to)

    {

        data[to] = data[from];

        data[from] = '.';

    }

    

    static boolean valid(char[] data, int k)

    {

        if(k<0 || k>=data.length) return false;

        return true;

    }

    

    static void f(char[] data)

    {

        while(true){

            boolean tag = false;

            for(int i=0; i<data.length; i++){

                int dd = 0; // 移动方向

                if(data[i]=='.') continue;

                if(data[i]=='A') dd = 1;

                if(data[i]=='B') dd = -1;

                

                if(valid(data, i+dd) && valid(data,i+dd+dd)

                && data[i+dd]!=data[i] && data[i+dd+dd]=='.'){

     
4000
           // 如果能跳...

                    move(data, i, i+dd+dd);

                    System.out.println(new String(data));

                    tag = true;

                    break;

                }

            }

            

            if(tag) continue;

            

            for(int i=0; i<data.length; i++){

                int dd = 0; // `移动方向

                if(data[i]=='.') continue;

                if(data[i]=='A') dd = 1;

                if(data[i]=='B') dd = -1;            

                    

                if(valid(data, i+dd) && data[i+dd]=='.'){

                // 如果能移动...

                    if( _____________________ ) continue;  //填空位置

                    move(data, i, i+dd);

                    System.out.println(new String(data));

                    tag = true;

                    break;

                }

            }

            

            if(tag==false) break;                    

        }

    }

    

    public static void main(String[] args)

    {

        char[] data = "AAA.BBB".toCharArray();    

        f(data);

    }

}

注意:只提交划线部分缺少的代码,不要复制已有代码或填写任何多余内容。

答案:valid(data, i+dd+dd) && valid(data,i-dd)&&data[i+dd+dd]==data[i-dd]

解题必备知识

在求解这道题之前,你需要先弄懂java基础中continue和break的区别,如果你连这两条语句是干什么的都不知道,那我就可以建议你了:放弃吧!孩子。

所以在此先说明一下这两条语句的区别

cotinue顾名思义是继续的意思嘛,那么是怎么个继续法呢

来上一段代码就看的很清楚了

for(int i=0;i<10;i++){

    if(i==3)continue;    

    System.out.print(i+" ");    

}

System.out.print(" 结束了");

看看运行后的结果:0 1 2 4 5 6 7 8 9 结束了

不知道此时你发现没有,结果中少了一个数字:3

回来阅读代码,当i=3是执行了continue语句,也就是说,循环跳过了i=3时continue后面的执行语句接着从i=4继续执行。

到此为止,你应该知道continue的作用了吧!调过本次循环中continue后面的执行语句,直接开始接下来的循环

continue适应于所有的循环for while中都可以使用

那么break又是干什么的呢?

看看break中文是什么意思:打破。那么要打破什么呢?看完下面一段估计你就知道了

依然呈上一段代码,帮助理解

for(int i=0;i<10;i++){

    if(i==3)break;    

    System.out.print(i+" ");    

}

System.out.print(" 结束了");

写完代码,来看看运行结果:0 1 2 结束了

哦?2后面的所有数字都没有了,你是不是发现了break的作用呢?当然是跳出for循环,接着执行for循环下面的语句

好,基本知识必备了,我们下面来看本道题的代码,强调一点,一定要仔细阅读每一句,因为代码中几乎每一句都是不能省略的,

都有其逻辑作用

解题思路:

我们开始解析代码,一定要保持住耐心,
package SevenProvience.test3;

public class Main
{
//·和字母位置的交换
static void move(char[] data, int from, int to)
{
data[to] = data[from];
data[from] = '.';
}
//判断数字k处是不在字符长度范围内
static boolean valid(char[] data, int k)
{
if(k<0 || k>=data.length) return false;
return true;
}
//·跳的过程
static void f(char[] data)
{
while(true){
boolean tag = false;
for(int i=0; i<data.length; i++){
int dd = 0; // 移动方向
if(data[i]=='.') continue;
if(data[i]=='A') dd = 1;
if(data[i]=='B') dd = -1;
//满足·AB或者AB·的情况跳,并且要判断是否在开始或者结尾对应的位置
if(valid(data, i+dd) && valid(data,i+dd+dd)
&& data[i+dd]!=data[i] && data[i+dd+dd]=='.'){
// 如果能跳...
move(data, i, i+dd+dd);
System.out.println(new String(data));

tag = true;
break;
}
}
//如果满足valid(data, i+dd) && valid(data,i+dd+dd) && data[i+dd]!=data[i] && data[i+dd+dd]=='.'
//跳过后面的语句从新while循环
if(tag) continue;

for(int i=0; i<data.length; i++){
int dd = 0; // `移动方向
if(data[i]=='.') continue;
if(data[i]=='A') dd = 1;
if(data[i]=='B') dd = -1;

if(valid(data, i+dd) && data[i+dd]=='.'){
// 如果能移动...
//如果满足BA·B、AA·A、A·BA、B·BB并且又不在开始或者结尾对应的位置跳过continue后面的语句继续下一次for循环
if(valid(data, i+dd+dd) && valid(data,i-dd)&&data[i+dd+dd]==data[i-dd]) continue;  //填空位置
move(data, i, i+dd);
System.out.println(new String(data));
tag = true;
break;
}
}

if(tag==false) break;
}
}
//主函数
public static void main(String[] args)
{
char[] data = "AAA.BBB".toCharArray();
System.out.println("AAA.BBB	");
f(data);
}
}
这是代入答案后的代码,如果你想思考怎么才能自己写出来答案,就需要你自己找规律了,前提是自己可以用笔画出来AAA·BBB—>BBB·AAA的所有过程

看完代码之后

在解AAA·BBB之前先建议你用笔画出A·B—>B·A的过程以及AA·BB—>BB·AA对于你解本题有非常大的帮助
然后附上几张我自己再解题时画的图,也就是本人的解题过程



条件3是一步一步摸索出来的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: