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

你的这个帖子到底是什么问题啊,最后也不留个话儿?

让我问的好辛苦的说。

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

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-06 00:54
蚕头燕尾
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 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);
    int askIfPrint();
    void putInTurn(int n,int sumNum,int ifPrint);

    //主函数中的变量定义
    int i,sumSolution=0;
    int rememberPrint;

    //确定是否进行打印所有情况
    rememberPrint=askIfPrint();

    for(i=2;i<=9;i++)
    {
        putInTurn(1,i,rememberPrint);
        sumSolution+=count;
        printf("\t当连接%d个点时候有%d种连法\n\t\t累计至此有%d种连法\n\n\n",i,count,sumSolution);   
        count=0;
    }
    printf("\n\n所以,总共有%d种可能的连接方法。\n\n\n",sumSolution);

    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();
}

//询问是否打印所有情况
int askIfPrint()
{
    int boo;
    printf("\n\n\t\t\t九宫格锁屏程序\n\n");
    printf("你是否想知道每一次的具体连法:\n");
    printf("1.是的,我想看看具体是怎么连的。(提示:情况非常之多)\n");
    printf("2.不,我不必知道具体都是怎么连的,我只想知道有多少种情况。\n\t\t我选择:");

    scanf("%d",&boo);

    if(boo==1)
        return 1;
    else
        return 0;
}


                                                            //        _________________        //
                                                            //                                //
                                                            //        判断能否放在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;
    }
   
}





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

void putInTurn(int n,int sumNum,int ifPrint)
{
    int i,j;

    if(n==sumNum+1)
    {
        //已经放置完9个结点,进行计数。
        count++;
        if(ifPrint)
        {
            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,sumNum,ifPrint);

                //这个语句很重要!这是递归能否进行的决定性语句。
                record[i][j]=0;
            }

        }

    }

}


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

                                                                                                                    Black Cat      Hello Tomorrow~
2013-06-06 20:22
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
收藏
得分:0 
经过复制粘贴,除了注释部分有一点变形之外,其余部分应该没有什么排版变形

欢迎大家对我的代码包括风格在内的所有缺陷提出批评指正。

如果有更好的算法欢迎提出建议。

谢谢

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

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



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

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