| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6975 人关注过本帖, 1 人收藏
标题:九宫格(基于安卓手机锁)九个点都连的时候有几种连法(递归实现)自己写的 ...
只看楼主 加入收藏
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
结帖率:96.08%
收藏(1)
 问题点数:0 回复次数:16 
九宫格(基于安卓手机锁)九个点都连的时候有几种连法(递归实现)自己写的有点问题
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>


                                                            //        ______        //
                                                            //                    //
                                                            //     定义全局变量    //
                                                            //                    //
                                                            //        ~~~~~~        //

//记忆哪个位置放了结点的数组
int record[3][3]={0};

//计数(有多少种情况)变量
int count=0;

//记录待放入的结点的前一个结点的坐标(通过函数查找后暂时放在这里)
int iBefTemp=-1,jBefTemp=-1;




                                                            //        ______        //
                                                            //                    //
                                                            //        主函数        //
                                                            //                    //
                                                            //        ~~~~~~        //

int main()
{
    //函数声明
    void befNodePos(int n);
    int checkLine(int i);
    int checkList(int j);
    int checkCorner(int i,int j);
    void print(int a[3][3]);
    int ifCanPut(int i,int j,int n);
    void putInTurn(int n);
   
    putInTurn(1);

    return 0;
}



                                                            //        ______        //
                                                            //                    //
                                                            //     其他函数定义    //
                                                            //                    //
                                                            //        ~~~~~~        //

//找到前一个结点的坐标并将坐标值放置在全局变量iBefTemp和jBefTemp里
void befNodePos(int n)
{
    int i,j;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            if(record[i][j]==n-1)
            {
                iBefTemp=i;
                jBefTemp=j;
                return;
            }

        }

    }

}

//判断间隔位置是否有结点放置。(横向判断)
int checkLine(int i)
{
    if(record[i][1]==0)
        return 0;
    else
        return 1;
}

//判断间隔位置是否有结点放置。(纵向判断)
int checkList(int j)
{
    if(record[1][j]==0)
        return 0;
    else
        return 1;
}

//判断ij位置是否为顶角位置
int checkCorner(int i,int j)
{
    if(i+j==2&&i!=j||i+j==0||i+j==4)
        return 1;
    else
        return 0;
}

//打印的函数
void print(int a[3][3])
{
    int i,j;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            printf("%3d",a[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    getch();
}



                                                            //        _________________        //
                                                            //                                //
                                                            //        判断能否放在ij位置        //
                                                            //                                //
                                                            //        ~~~~~~~~~~~~~~~~~~        //

int ifCanPut(int i,int j,int n)
{
    //如果这个位置还没有放置结点
    if(record[i][j]==0)
    {
        //找到前一个结点的坐标放在全局变量里面
        //如果是在放置第一个结点,则不必找它的前一个结点,任何一个位置都是合适的。
        if(n==1)
        {
            //因为是放置第一个结点,所以不必判断它跟前一个结点的关系
            return 1;
        }

        //放置除了第一个结点之外的结点,需要判断它个前一个结点的关系。
        else if(n<=9)
        {   
            iBefTemp=-1;
            jBefTemp=-1;
            befNodePos(n);

            //当中间有间隔位置时(横向判断)。
            if(i==iBefTemp&&abs(j-jBefTemp)==2)
            {
                //判断间隔位置是否有结点放置。
                if(checkLine(i))
                {
                    //已经有结点
                    //////////////可以放置........
                    return 1;
                }
                else
                {
                    //没有结点放置
                    ///////////////不能放置在ij这里
                    return 0;
                }

            }

            //当中间有间隔位置时(纵向判断)。
            else if(j==jBefTemp&&abs(i-iBefTemp)==2)
            {
                //判断间隔位置是否有结点放置。
                if(checkList(j))
                {
                    //已经有结点
                    //可以放置.............
                    return 0;
                }
                else
                {
                    //没有结点
                    //////////////不能放置在ij这里
                    return 0;
                }

            }

            //当二者为对角关系时
            else if(checkCorner(i,j)&&checkCorner(iBefTemp,jBefTemp)&&(i!=iBefTemp&&j!=jBefTemp))
            {
                //判断中间位置是否有结点放置。
                if(record[i][j]!=0)
                {
                    //中间位置已经放置了结点
                    //可以放置在ij......
                    return 1;
                }
                else
                {
                    //中间位置没有放置结点,不能放置在ij
                    return 0;
                }   

            }

            //二者中间没有间隔位置,从而可以直接放置。
            else
            {
                //可以放置...........
                return 1;
            }
        }
    }

    //如果这个位置已经放置了结点,不能放置结点
    else
    {
        return 0;
    }
   
    //if(button==1)
    //{
    //    return 1;
    //    /*record[i][j]=n;
    //    putInTurn(n+1);*/
    //}
    //else
    //{
    //    return 0;
    //}
}





                                
                                                            //        ______        //
                                                            //                    //
                                                            //        主算法        //
                                                            //                    //
                                                            //        ~~~~~~        //

void putInTurn(int n)
{
    int i,j;
    int boo;

    if(n==10)
    {
        //已经放置完9个结点
        count++;
        print(record);

        return;
    }

    //尝试将其放置在i行j列。
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            if(ifCanPut(i,j,n))
            {
                record[i][j]=n;
                putInTurn(n+1);
            }

        }

    }

    printf("count=%d\n",count);

}

搜索更多相关主题的帖子: 手机锁 九宫格 include 
2013-06-04 22:22
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
收藏
得分:0 
补充说明一下:
我为了简化问题,先只考虑将九个格都连起来的情况(暂时不考虑只连2、3、、、个格的情况)

遇到这个问题,我的第一反应是图论和递归。因为自己对图论可以说是一无所知,所以不知道我的这种想法是不是有点南辕北辙。所以希望有朋友能够点播一二。

或者有更好的算法来实现那就更好了。
还是提醒一下,我最终的目的是计算所有的情况,包括只连2、3、4、5、6、7、8个格的情况。所以算法最好要有普适性。
因为是复制过来的代码,所以可能在排版上有所变形,您可以复制到自己的编译器上重新排版,为了减少您敲代码的时间,我没有采用截图的方法

真心的求教,谢谢大家。

学习编程,为的是表达自己的思想,而不是被别人的思想所禁锢。要先明白自己想干嘛,而不要先问别人让你干嘛。               

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-04 22:30
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
收藏
得分:0 
另外这因为还不是最后的代码,所以调试过程中注释掉的部分没有删掉,可以这么说,注释部分,只要不是中文的,应该都可以忽略,不是起真正的注释作用。

静待朋友们的帮助。

学习编程,为的是表达自己的思想,而不是被别人的思想所禁锢。要先明白自己想干嘛,而不要先问别人让你干嘛。               

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-04 22:34
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
收藏
得分:0 
难道没有大神肯帮帮我?alright。。。

学习编程,为的是表达自己的思想,而不是被别人的思想所禁锢。要先明白自己想干嘛,而不要先问别人让你干嘛。               

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-05 01:06
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
你至少说一下是什么问题?输出不对、编译错误还是程序不能执行?


[fly]存在即是合理[/fly]
2013-06-05 08:42
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
收藏
得分:0 
不好意思,看来还是因为我的叙述不清,我自己感觉已经尽量表达我的意思了,额,突然感觉自己的语言表达能力弱爆了。。

是这样的,我的这个代码运行的结果count始终是等于1,

这是我自己的设计的一个递归算法,仿照的是八皇后问题的递归方法。
但是不知道是不是思路的问题,递归无法按照我的思路进行(具体表现就是:count没能按照预计的那样进行计数)

学习编程,为的是表达自己的思想,而不是被别人的思想所禁锢。要先明白自己想干嘛,而不要先问别人让你干嘛。               

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-05 23:11
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
收藏
得分:0 
这里我顺便把八皇后的代码贴出来吧
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>

int iCount=0;
int WeiZhi[8];

void Output()
{
    int i,j,flag=1;
    printf("第%2d种方案(*表示皇后):\n",++iCount);
    printf(" ");
    for(i=1;i<=8;i++)
    {
        printf("_");
    }
    printf("\n");
    for(i=0;i<8;i++)
    {
        printf(" |");
        for(j=0;j<8;j++)
        {
            if(WeiZhi[i]-1==j)
            {
                printf("*");
            }
            else
            {
                if(flag<0)
                {
                    printf(" ");
                }
                else
                {
                    printf("@");
                }

            }
            flag=-1*flag;

        }
        printf("| \n");
        flag=-1*flag;
    }
    printf(" ");
    for(i=1;i<=8;i++)
    {
        printf("-");
    }
    printf("\n");
    getch();
}

void EightQueen(int n)
{
    int i,j;
    int ct;
    if(n==8)
    {
        Output();
        return;
    }
    for(i=1;i<=8;i++)
    {
        WeiZhi[n]=i;
        //判断第n个皇后是否与前面的皇后形成攻击
        ct=1;
        for(j=0;j<n;j++)
        {
            if(WeiZhi[j]==WeiZhi[n])//形成攻击
            {
                ct=0;
            }
            else if(abs(WeiZhi[j]-WeiZhi[n])==(n-j))//形成攻击
            {
                ct=0;
            }
            else
            {
            }

        }
        if(ct==1)
        {
            EightQueen(n+1);
        }

    }

}

int main()
{
    printf("八皇后问题求解!\n");
    printf("八皇后排列方案:\n");
    EightQueen(0);

    return 0;
}


我就是想仿照这个递归设计我自己的递归,初次自己写这样的代码,还望有经验 的朋友多多指教。
谢谢。

学习编程,为的是表达自己的思想,而不是被别人的思想所禁锢。要先明白自己想干嘛,而不要先问别人让你干嘛。               

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-05 23:14
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
你的record数组第一趟递归已经初始化为123456789了,再执行ifCanPut只会返回 0,所以count不会再加,解决办法是
程序代码:
for(i=0;i<3;i++)
{
    for(j=0;j<3;j++)
    {
        if(ifCanPut(i,j,n))
        {
            record[i][j] = n;
            putInTurn(n+1);
            record[i][j] = 0;
        }
    }
}


ifCanPut函数没有看,所以不保证没有其他逻辑错误


[fly]存在即是合理[/fly]
2013-06-05 23:55
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
顺便说点吧,这个用全排列的思路做会好些


[fly]存在即是合理[/fly]
2013-06-06 00:01
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
收藏
得分:0 
回复 8楼 azzbcc
ifCanPut函数我单独测试过,应该不会有什么问题,按照你说的那样改了之后,确实count计数了,但最后输出count结果是个很大的数,感觉可能有点不太靠谱,我再看看有没有其他错误,谢谢哈~~

学习编程,为的是表达自己的思想,而不是被别人的思想所禁锢。要先明白自己想干嘛,而不要先问别人让你干嘛。               

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-06 00:07
快速回复:九宫格(基于安卓手机锁)九个点都连的时候有几种连法(递归实现)自己 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019775 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved