zoukankan      html  css  js  c++  java
  • 第七届蓝桥杯C/C++程序设计本科B组决赛 ——棋子换位(代码补全题)


    棋子换位

    有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换位的功能,请仔细阅读分析源码,填写划线部分缺失的内容。

    #include <stdio.h>
    #include <string.h>

     1 void move(char* data, int from, int to)//移动一个棋子A或者B到空位上
     2 {
     3     data[to] = data[from];
     4     data[from] = '.';
     5 }
     6 
     7 int valid(char* data, int k)//判断是否越界
     8 {
     9     if(k<0 || k>=strlen(data)) return 0;
    10     return 1;
    11 }
    12 
    13 void f(char* data)
    14 {
    15     int i;
    16     int tag;
    17     int dd = 0; // 移动方向
    18 
    19     while(1){
    20         tag = 0;
    21         for(i=0; i<strlen(data); i++){
    22             if(data[i]=='.') continue;
    23             if(data[i]=='A') dd = 1;
    24             if(data[i]=='B') dd = -1;
    25 
    26             if(valid(data, i+dd) && valid(data,i+dd+dd)
    27             && data[i+dd]!=data[i] && data[i+dd+dd]=='.'){
    28             //如果能跳...
    29                 move(data, i, i+dd+dd);
    30                 printf("jump:%s
    ", data);
    31                 tag = 1;
    32                 break;
    33             }
    34         }
    35 
    36         if(tag) continue;
    37 
    38         for(i=0; i<strlen(data); i++){
    39             if(data[i]=='.') continue;
    40             if(data[i]=='A') dd = 1;//向右
    41             if(data[i]=='B') dd = -1;//向左
    42 
    43             if(valid(data, i+dd) && data[i+dd]=='.'){
    44             // 如果能移动...
    45                 if(valid(data, i+dd+dd) && valid(data,i-dd)&&data[i+dd+dd]==data[i-dd] ) continue;  //填空位置
    46                 move(data, i, i+dd);
    47                 printf("move:%s
    ", data);
    48                 tag = 1;
    49                 break;
    50             }
    51         }
    52 
    53         if(tag==0) break;
    54     }
    55 }
    56 
    57 int main()
    58 {
    59     char data[] = "AAA.BBB";
    60     printf("%s
    ",data);
    61     f(data);
    62     return 0;
    63 }
    View Code

    思路:

    以下为程序运行时的输出: 

    初始:AAA.BBB
    move:AA.ABBB
    jump:AABA.BB
    move:AABAB.B
    jump:AAB.BAB
    jump:A.BABAB
    move:.ABABAB
    jump:BA.ABAB
    jump:BABA.AB
    jump:BABABA.
    move:BABAB.A
    jump:BAB.BAA
    jump:B.BABAA
    move:BB.ABAA
    jump:BBBA.AA
    move:BBB.AAA

    仔细想想,还是有规律的;注意看上面的第二行和第三行,从第二行的状态出发,走一次‘B’之后达到了一个状态:空点两侧都是‘B’了,也就是说空地两侧是相同的字符!——这个时候就不能再把最后一个B再向左移动(move)了,不然就卡死了!

        下面的几个画横线的都是这样!这种题目确实不好想,解题思路应该进行一些调整,自己按照规则尝试运行运行,在自己模拟的过程中逐步发现规律,毕竟去掉这一行以后经常进入死循环!

  • 相关阅读:
    linux文件权限查看及修改(实用)
    将JSON对象带有格式的写出到文件中
    mySQL数据库Sql语句执行效率检查--Explain命令
    mysql优化
    Linux-设置固定IP
    logback 配置详解(二)——appender
    logback 配置详解(一)——logger、root
    Thread
    Singleton
    多线程编程总结
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/9041818.html
Copyright © 2011-2022 走看看