• 【C/C++】习题3-5 谜题/算法竞赛入门经典/数组和字符串


    【题目】
    有一个5*5的网络,恰好有一个格子是空的(空格),其他格子各有一个字母。
    指令:A, B, L, R 把空格上、下、左、右的相邻字母移到空格中。
    【输入】
    初始网格和指令序列(以数字0结束)。
    【输出】
    指令执行完毕后的网格。
    如果有非法指令,输出"This puzzle has no final configuration."。
    【知识点】

    1. scanf输入带空格的输入,scanf的多次使用
      https://www.cnblogs.com/kinologic/p/13957927.html

    2. 二维数组的传参方式
      https://www.cnblogs.com/kinologic/p/13958685.html
      我这里用了文章中的第二种方式。第一种方式和第二种方式都还比较简单。第三种方法要用到二级指针了,略显复杂。
      首先是在主函数中定义了二维数组:

      其次是在子函数中的引用:

    3. switch-case分支语句一定要写break!
      break的作用是结束当前的switch语句,如果删去,则程序将会从第一个匹配的case开始执行语句,直到其下面的所有语句都执行完毕才会退出switch。

    4. 多组数据的返回
      刚开始写的时候脑子不太好用,看有用结构体/传指针的方式。
      但是后来意识到有小题大做了,其实直接用C++引用传int的引用就行了。

    5. 二维数组的坐标
      a[x][y]
      x是行,y是列
      修改行:x 上- 下+
      修改列:y 左- 右+

    【代码】

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    const int maxn = 100;
    using namespace std;
    
    void alert()
    {
        printf("This puzzle has no congiruation
    ");
    }
    
    void show_matrix(char(*a)[10])
    {
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                printf("%c", a[i][j]);
            }
            printf("
    ");
        }
    }
    
    void get_empty(char(*a)[10], int& x, int& y) //由于对值由修改,必须传引用
    {
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                if (a[i][j] == ' ')  //if后面两句要打括号,不然只会执行一句
                {
                    x = i;
                    y = j;
                }
            }
        }
    }
    
    void move_empty(char c, char(*a)[10], int& x, int& y) //对值没有修改,不传引用也可以
    {
        switch(c)
        {
            case 'A': //把空格上方的相邻字母移到空格中
            {
                if (x == 0) alert(); 
                else
                {
                    a[x][y] = a[x-1][y];
                    a[x-1][y] = ' ';
                }
            }
            break;
    
            case 'B': //把空格下方的相邻字母移到空格中
            {
                if (x == 4) alert();
                else
                {
                    a[x][y] = a[x+1][y];
                    a[x+1][y] = ' ';
                }            
            }
            break;
    
            case 'L': //把空格左方的相邻字母移到空格中
            {
                if (y == 0) alert();
                else
                {
                    a[x][y] = a[x][y-1];
                    a[x][y-1] = ' ';
                }           
            }
            break;
    
            case 'R': //把空格右方的相邻字母移到空格中
            {
                if (y == 4) alert();
                else
                {
                    a[x][y] = a[x][y+1];
                    a[x][y+1] = ' ';
                }           
            }
            break;
        }
        
    }
    
    int main()
    {
        char s[maxn]; //暂存用
        char a[10][10]; //存储题目矩阵,a是二维数组(二级指针)
        //坐标参数指针
        int x = 0, y = 0; //位置坐标
    
        //输入题目矩阵:五行输入 带空格
        for (int i = 0; i < 5; i++)
        {
            scanf("%[^
    ]",s);
            for (int j = 0; j < 5; j++)
            {
                a[i][j] = s[j];
            }
            fflush(stdin);
        }
    
        //printf("out
    ");
        //show_matrix(a);
    
        //输入指令序列
        fflush(stdin);
        scanf("%s",s);
        int n = strlen(s);
    
        //检测是否为合法指令
        int flag = 1;
        for (int i = 0; i < n-1; i++)
        {
            if(s[i] != 'A' && s[i] != 'B' && s[i] != 'L' && s[i] != 'R') //用“或”有错误
            {
                flag = 0;
                break;
            }
        }
        //printf("1flag %d
    ",flag);
        if ( s[n-1] != '0' ) flag = 0;
        //printf("2flag %d
    ",flag);
        if (flag == 0) alert();
    
        //若为合法指令
        else 
        {
            for (int i = 0; i < n-1; i++)
            {
                get_empty(a, x, y);
                printf("empty: x is %d, y is %d
    ", x, y);
                move_empty(s[i], a, x, y); //执行命令
            }
            show_matrix(a);
        }
        system("pause");
    }
    

    【心得】
    C的指针真是太麻烦了,用不起就用C++的引用(

  • 相关阅读:
    火狐插件火狐黑客插件将Firefox变成黑客工具的七个插件
    memcache安装环境:WINDOWS 7
    PHP正则表达式
    968. 监控二叉树 力扣(困难) dfs 官方说DP
    375. 猜数字大小 II 力扣(中等) 区间动态规划、记忆化搜索
    629. K个逆序对数组 力扣(困难) 区间动态规划
    剑指 Offer 51. 数组中的逆序对 力扣(困难) 巧用归并排序算法
    488. 祖玛游戏 力扣(困难) dfs
    16. 最接近的三数之和 力扣(中等) 双指针
    319. 灯泡开关 力扣(中等) 数论
  • 原文地址:https://www.cnblogs.com/kinologic/p/13964795.html
Copyright © 2020-2023  润新知