求助,求思路,7*7数组中找出相同且相邻的元素
想做一个消除类小游戏,就是需要判断,数组中相同且联通的元素,如果大于3则消除该,怎么弄啊,求思路。。。
-----------------------------------------
1 2 3 4 5 6 7
2 5 5 5 5 7 8
3 5 5 5 6 6 8
4 2 2 2 2 2 3
5 2 2 1 1 2 3
6 5 2 3 3 1 4
7 6 6 7 8 9 9
-----------------------------------
如这里相邻且大于3个联通的有 8个5,6个2,怎么找出来好啊,试了好久都没有解决。。。用的是递归,可能是用的不太正确,希望指出明路
[解决办法]
直接递归深搜就可以了吧?
搜索过程中,用一个相同的bool数组记录某结点是否被访问过。
每次都从一个没有访问过的结点开始向4个方向搜索数字相同的,直到走不动为止。如果大于3就消除它。继续上面过程。
[解决办法]
加一个7x7的状态表。
算法开始时,从0,0开始检查
1. 标记该点已检查,
2. 对该点的联通点进行搜索。
搜索结束时继续下个点并判断是否已经被联通过。没连通过,则做1和2。否则,跳过这个点。
搜索的算法,就是对一个点周围的4个点检查,找到一样的,然后继续对这些一样的点进行检查。直到没有需要检查的点为止。
这个应该实现起来不难吧..
[解决办法]
感觉挺好玩的,试着搞了一个,仅供参考,效率问题欢迎大牛批评指正:)
#define LINE 7
#define ROW 7
// 搜索与第i行第j列值相同的联通点,如果联通点超过2个则输出对应的信息
void fun(int p[][ROW], int i ,int j)
{
bool b[LINE][ROW] = {0}; // 是否已搜索过
int n = p[i][j]; // 当前要判断的值
int nNum[4] = {0}; // 联通的方向索引 0:左;1:右;2:上;3:下
int nCount = 1; // 计数器
// 初始化方向索引
nNum[0] = j;
nNum[1] = j;
nNum[2] = i;
nNum[3] = i;
//向左搜索
if (j != 0)
{
for (int h = j - 1; h != 0; --h)
{
if (!b[i][h])
{
b[i][h] = true;
if (p[i][h] == n )
{
nNum[0] = h;
nCount++;
}
else
{
break;
}
}
}
}
//向右搜索
if (j != ROW-1)
{
for (int h = j + 1; h != ROW; ++h)
{
if (!b[i][h])
{
b[i][h] = true;
if (p[i][h] == n )
{
nNum[1] = h;
nCount++;
}
else
{
break;
}
}
}
}
//向上搜索
if (i != 0)
{
for (int h = i - 1; h != -1; --h)
{
if (!b[h][j])
{
b[h][j] = true;
if (p[h][j] == n )
{
nNum[2] = h;
nCount++;
}
else
{
break;
}
}
}
}
//向下搜索
if (i != LINE-1)
{
for (int h = i + 1; h != LINE; ++h)
{
if (!b[h][j])
{
b[h][j] = true;
if (p[h][j] == n )
{
nNum[3] = h;
nCount++;
}
else
{
break;
}
}
}
}
if (nCount > 2)
{
cout << "与["<<i<<"]["<<j<<"]联通的点:"<< nCount <<" 左起:" << nNum[0] << " 右至:" << nNum[1] << " 上起:" << nNum[2] << " 下至:" << nNum[3] << endl;
}
else
cout << "与["<<i<<"]["<<j<<"]联通的点不足3个!" << endl;
}
int main(int argc, _TCHAR* argv[])
{
int n[LINE][ROW] = {
{2, 4, 6, 5, 4, 3, 2},
{2, 6, 6, 6, 6, 3, 2},
{2, 1, 6, 5, 4, 3, 5},
{4, 4, 6, 5, 4, 3, 2},
{2, 4, 6, 3, 4, 3, 2},
{5, 4, 6, 5, 4, 2, 2},
{2, 4, 6, 5, 4, 3, 20},
};
// 测试一下
for (int i = 0; i != LINE; ++i)
{
for (int j = 0; j != ROW; ++j)
{
fun(n ,i ,j);
}
}
return 0;
}
#define LINE 7
#define ROW 7
bool b[LINE][ROW] = {0}; // 记录是否与当前处理的索引位置联通
UINT nCount = 0; // 联通的结点数
// 递归搜索与第i行第j列值相同的联通点,如果相同将其联通标志置为true,联通计数+1
void fun(int p[][ROW], int i ,int j)
{
int n = p[i][j]; // 当前要判断的值
//向左搜索
if (j != 0)
{
for (int h = j - 1; h != -1; --h)
{
if (!b[i][h])
{
if (p[i][h] == n )
{
b[i][h] = true;
nCount++;
fun(p, i ,h);
}
else
{
break;
}
}
}
}
//向右搜索
if (j != ROW-1)
{
for (int h = j + 1; h != ROW; ++h)
{
if (!b[i][h])
{
if (p[i][h] == n )
{
b[i][h] = true;
nCount++;
fun(p, i ,h);
}
else
{
break;
}
}
}
}
//向上搜索
if (i != 0)
{
for (int h = i - 1; h != -1; --h)
{
if (!b[h][j])
{
if (p[h][j] == n )
{
b[h][j] = true;
nCount++;
fun(p, h ,j);
}
else
{
break;
}
}
}
}
//向下搜索
if (i != LINE-1)
{
for (int h = i + 1; h != LINE; ++h)
{
if (!b[h][j])
{
if (p[h][j] == n )
{
b[h][j] = true;
nCount++;
fun(p, h ,j);
}
else
{
break;
}
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
srand((UINT)time(NULL));
int n[LINE][ROW] = {0} ;
// 随机初始化
for (int i = 0; i != LINE; ++i)
{
for (int j = 0; j != ROW; ++j)
{
n[i][j] = rand()%4;
cout << n[i][j] << " ";
}
cout << endl;
}
fun(n ,3 ,3); // 测试一下中间位置的联通情况
cout << "==============================" << endl;
if (nCount == 0) // 如果自身周围都没有相同的
{
nCount++; // 联通数加上自身
}
if (nCount > 2)
{
cout << "联通数 "<<nCount<< endl;
for (int i = 0; i != LINE; ++i)
{
for (int j = 0; j != ROW; ++j)
{
if (b[i][j])
{
cout << "- ";
}
else
{
cout << n[i][j] << " ";
}
}
cout << endl;
}
}
else
cout << "联通数 "<<nCount<<" 不足3" << endl;
return 0;
}
const int M=7;
const int N=7;
int nCount=0;
int a[M][N]=
{
1,2,3,4,5,6,7,
2,5,5,5,5,7,8,
3,5,5,5,6,6,8,
4,2,2,2,2,2,3,
5,2,2,1,1,2,3,
6,5,2,3,3,1,4,
7,6,6,7,8,9,9
};
void solve(int i,int j,int value)
{
if(i>=0 && i<M && j>=0 && j<N)
{
if(a[i][j]==value)
{
nCount++;
a[i][j]=-1;
solve(i,j+1,value);
solve(i+1,j,value);
solve(i,j-1,value);
solve(i-1,j,value);
}
}
}
int main()
{
int i,j;
nCount=0;
scanf("%d%d",&i,&j);
solve(i,j,a[i][j]);
printf("%d\n",nCount);
return 0;
}