首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

,求思路,7*7数组中找出相同且相邻的元素

2013-03-29 
求助,求思路,7*7数组中找出相同且相邻的元素想做一个消除类小游戏,就是需要判断,数组中相同且联通的元素,

求助,求思路,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;
}


[解决办法]
引用:
感觉挺好玩的,试着搞了一个,仅供参考,效率问题欢迎大牛批评指正:)


C/C++ code
?



12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747……
更正一下23行h != -1
------解决方案--------------------


泡泡龙的游戏?

[解决办法]
直接递归收索
[解决办法]
std::adjacent_find 
[解决办法]
刚才给的代码考虑的是十字型的联通情况,现在来个升级版,可以拐弯联通的

#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;
}

热点排行