刚学C++编程一个多月,我就是个渣渣啊,算法啊数据结构啊基础为负。
测试输入为
这个采用最直接打办法解决的宝石迷阵消除算法,里面的代码乱七八糟的,等我学点算法再回来看吧。
#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;
}