一个采用BF算法的宝石迷阵的消除解法

刚学C++编程一个多月,我就是个渣渣啊大哭,算法啊数据结构啊基础为负。

测试输入为

2//有几次测试
4 5//地图规模,4行5列,都是自己输入的,可以更改的
.D.M.
.DCAE
.AABA
MDDAM//创建地图,'.'代表没有元素
2 3 2 4//交换(2,3)(2,4),注意左上角为(0,0)
2 4 //第二次测试
F.Z.
ZZAZ
1 2 0 2

输出应该为消除了多少个宝石
8//第一次消除了8个,就跟普通的消除游戏一样嘛
4

这个采用最直接打办法解决的宝石迷阵消除算法,里面的代码乱七八糟的,等我学点算法再回来看吧。

#include <iostream>
#include <vector>
#include <algorithm>

#include <cstdlib>
#include <ctime>
using namespace std;


int result = 0;
int judge(char **Map, int row, int col);
void createElement(char **Map, int row, int col);
void showMap(char **Map, int row, int col);
int countSpace(char **Map, int row, int col);


int main()
{
    int testPoint = 0;
    cin >> testPoint;


    for ( int i = 0; i < testPoint; ++i)
    {
        int row = 0;
        cin >> row;
        int col = 0;
        cin >> col;


        //分配内存
        char **Map = new char*[row +1];
        for (int i = 0; i < row; ++i)
        {
            Map[i] = new char[col + 1];
        }


        for (int i = 0; i < row; ++i)
            for (int j =0; j < col; ++j)
            {
                cin >> Map[i][j];
            }


        int x1, y1, x2, y2;
        cin >> x1 >> y1;
        cin >> x2 >> y2;


        char temp = Map[x1][y1];
        Map[x1][y1] = Map[x2][y2];
        Map[x2][y2] = temp;
       // cout << "Log : exchange.\n";


        int first = countSpace(Map, row, col);


        int x = judge(Map, row, col);


        int last = countSpace(Map, row, col);


        cout << last - first << endl;
    }


    return 0;
}


int judge(char **Map, int row, int col)
{




    vector<char *> vCharTemp;
    //遍历检查是否有需要被删除的元素


    //检查每一横排,把三个以上相同的放入容器,做边界检测
    for (int i = 0; i < row; ++i)
    {
        for (int j = 0; j < col; ++j)
        {




            if (Map[i][j] == '.')
                continue;
            if (j + 2 >= col)
                continue;
            if (Map[i][j] != Map[i][j+1])
                continue;
            if (Map[i][j] != Map[i][j+2])
                continue;
            vCharTemp.push_back(&Map[i][j]);
            vCharTemp.push_back(&Map[i][j+1]);
            vCharTemp.push_back(&Map[i][j+2]);
            //TODO下一次检测可以直接越过这三个元素
            if (j + 3 < col && Map[i][j] == Map[i][j+3])
            {
                vCharTemp.push_back(&Map[i][j+3]);
                if (j + 4 < col && Map[i][j] ==Map[i][j+4])
                {
                    vCharTemp.push_back(&Map[i][j+4]);
                }
            }
        }
    }


    //cout << "Log : check the col.\n";
    //检查每一竖列
    for (int i = 0; i < row; ++i)
    {
        for (int j = 0; j < col; ++j)
        {
            if (Map[i][j] == '.')
                continue;
            if (i + 2 >= row)
                continue;
            if (Map[i][j] != Map[i+1][j])
                continue;
            if (Map[i][j] != Map[i+2][j])
                continue;
            vCharTemp.push_back(&Map[i][j]);
            vCharTemp.push_back(&Map[i+1][j]);
            vCharTemp.push_back(&Map[i+2][j]);
            if (i + 3 < row && Map[i][j] == Map[i+3][j])
            {
                vCharTemp.push_back(&Map[i+3][j]);
                if (i + 4 < row && Map[i][j] == Map[i+4][j])
                {
                    vCharTemp.push_back(&Map[i+4][j]);
                }
            }
        }
    }


    //cout << "Log : check the row.\n";


    //根据容器的大小统计这一轮一共消除了多少个,如果存在指向相同的元素的指针只计算一次。
    auto end_unique = unique(vCharTemp.begin(), vCharTemp.end());
    vCharTemp.erase(end_unique, vCharTemp.end());//剔除相同的元素


    result += vCharTemp.size();
    if (vCharTemp.size() == 0)//如果容器里面一个元素都没有,则返回结果
    {
        return result;
    }
    //已经将需要消除的放进容器里面了,然后将他们全部置为'.'
    for (auto mem : vCharTemp)
        *mem = '.';
    //cout << "Log : delete the same element.\n";


    //现在解决下落的问题,从下往上遍历,如果元素是'.'且上面不是'.'就将他们跟'.'调换
    int cunt = 0;
    do
    {
        cunt++;
        for (int i = row - 1; i > 0; --i)//卧槽这儿写成 ++i了
        {
            for (int j = 0; j < col; ++j)
            {
                //怎么解决连续的'.'呢,从上往下再遍历一次?外面在加一个循环貌似可以解决
                if (Map[i - 1][j] != '.' && Map[i][j] == '.')
                {
                    char temp = Map[i - 1][j];
                    Map[i - 1][j] = Map[i][j];
                    Map[i][j] = temp;
                }
            }
        }
    }while (cunt < row);//直至'.'到最上面
   // cout << "Log : Drop the element.\n";


    //现在地图已经重新生成且'.'都在上面,先重新生成新元素替换'.'
    showMap(Map, row, col);
    //createElement(Map, row, col);
    //showMap(Map, row, col);


    //递归调用判断新地图是否存在可以消除的元素,直至容器大小为0;


    int x = judge(Map, row, col);
    
    for (int i = 0; i < row; ++i)
    {
        delete Map[i];
    }


}


void createElement(char **Map, int row, int col)
{
    srand(time(0));
   // cout << "Log : create new map.\n";
    for (int i = 0; i < row; ++i)
    {
        for (int j = 0; j < col; ++j)
        {
            if (Map[i][j] == '.')
            {
                int key = rand() % 26;
                Map[i][j] = 'A' + key;
            }
        }
    }
}


void showMap(char **Map, int row, int col)
{
    for (int i = 0; i < row; ++i)
    {
         for(int j = 0; j < col; ++j)
        {
            cout << Map[i][j];
        }
        cout << endl;
    }
    cout << "-----" << endl;
}


int countSpace(char **Map, int row, int col)
{
    int cunt = 0;
    for (int i = 0; i < row; ++i)
    {
        for (int j = 0; j < col; ++j)
        {
            if (Map[i][j] == '.')
                cunt++;
        }
    }
    return cunt;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值