| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 30182 人关注过本帖
标题:麻将胡牌算法
只看楼主 加入收藏
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
不是数组越界不越界的问题

int a[15]={1, 2, 2, 3, 3, 4,  5, 5, 6, 6,  8, 8, 9, 9};


[fly]存在即是合理[/fly]
2013-01-15 11:39
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
没考虑数组越界,所以又有新问题了

int a[15]={1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 9, 9, 9};//是胡牌


[fly]存在即是合理[/fly]
2013-01-15 11:56
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
仔细想了一下,12楼例子与数组越界无关,噢,建议斑竹重新想一个吧

[ 本帖最后由 azzbcc 于 2013-1-15 12:02 编辑 ]


[fly]存在即是合理[/fly]
2013-01-15 12:00
qunxingw
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:24
帖 子:1676
专家分:7295
注 册:2011-6-30
收藏
得分:0 
回复 13楼 azzbcc
谢谢,这个问题找到了,查了下,发现选将不胡牌时,要恢复原来的数据。需要调整,呵呵,

[ 本帖最后由 qunxingw 于 2013-1-15 13:34 编辑 ]

www.qunxingw.wang
2013-01-15 13:23
qunxingw
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:24
帖 子:1676
专家分:7295
注 册:2011-6-30
收藏
得分:0 
#include<iostream>
using namespace std;
int main()
{//测试数据{1,1,2, 3, 3, 4, 4, 5, 6, 6,8,8,9,9};
    //{1, 1, 1, 3, 3, 4, 4, 5, 5, 6, 6, 9, 9, 9};测试数据
    //{1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 9, 9, 9}
    cout<<"如果胡牌则显示,不胡牌则以下无输出"<<endl;  
    int i,j,k,x,temp,flat=0;//{1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 9, 9, 9}测试数据
   
    int a[15]={1, 1, 1, 3, 3, 4, 4, 5, 5, 6, 6, 9, 9, 9};// 牌已排序。
   
    for (x=0; x<14; x++)  //在数组最后位置加一个数,便以下判断是否全部清0
    {
        if(a[x]==a[x+1] && a[x]!=0)
        {
            temp=a[x];
            a[14]=a[x];
        }
        
        for(i=0; i<15; i++)                     //找出连续或相同的三个数,并标记为0
            for(j=0; j<15; j++)
                for(k=0; k<15; k++)   
                {
                    if(i==j||j==k||i==k) continue;
                    if(a[i]+1==a[j] && a[j]+1==a[k]&& a[i]!=0 || a[i]!=0 && a[i]==a[j] && a[k]==a[j] )
                    {
                        a[i]=0; a[j]=0; a[k]=0;
                    }
                }               
                int    s=0;   
                for(i=0;i<15;i++)   
                {
                //    cout<<a[i];
                    s+=a[i];
                }
            //    cout<<endl;
                if(s!=0)
                {
                    a[x]=temp;
                    a[x+1]=temp;
                    a[14]=0;        
                //    cout<<"  s="<<s<<endl;
                }
                if(s==0)
                {
                    cout<<"恭喜您!已胡牌!"<<endl;//如果数组里全部是0说明已胡牌,
                    
                       break;
                }
               
    }
   
    return 0;
}

www.qunxingw.wang
2013-01-15 20:41
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
跟进看了一下,后面 2个 6会被temp覆盖,所以应该还是有问题的,不过也许理解错了,算法还没看懂,额


[fly]存在即是合理[/fly]
2013-01-15 21:22
a425753262
Rank: 1
等 级:新手上路
帖 子:1
专家分:9
注 册:2013-1-15
收藏
得分:9 
回复 2楼 wp231957
汗颜!!!!
2013-01-15 21:43
qunxingw
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:24
帖 子:1676
专家分:7295
注 册:2011-6-30
收藏
得分:0 
以下是引用azzbcc在2013-1-15 21:22:20的发言:

跟进看了一下,后面 2个 6会被temp覆盖,所以应该还是有问题的,不过也许理解错了,算法还没看懂,额

的确还有问题,暂时想不出了。

www.qunxingw.wang
2013-01-15 21:51
qunxingw
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:24
帖 子:1676
专家分:7295
注 册:2011-6-30
收藏
得分:0 
程序代码:
#include<iostream>
using namespace std;
int main()
{
     
    int i,j,k,x,temp,flat=0;
    int b[14]={2,2,3,3,4,4,5,5,6,6,7,7,8,9};// 牌已排序。
 
    int a[14]={0};
    for(i=0; i<14; i++)
            a[i]=b[i];

    for (x=0; x<13; x++)  //在数组最后位置加一个数,便以下判断是否全部清0
    {
        if(a[x]==a[x+1]&& a[x]!=0 )//改变策略,除掉将牌
        {          
          a[x]=0;
          a[x+1]=0;
        }
       else continue;
     
        for(i=0; i<14; i++)                     //找出连续或相同的三个数,并标记为0
            for(j=0; j<14; j++)
                for(k=0; k<14; k++) 
                {
                    if(i==j||j==k||i==k) continue;
                    if( a[i]==a[j] && a[k]==a[j]||a[i]+1==a[j] && a[j]+1==a[k]&& a[i]!=0  )
                    {
                        a[i]=0; a[j]=0; a[k]=0;
                    }
                }             
                int    s=0; 
                for(i=0;i<14;i++) 
                  {
                s+=a[i];
                    }
              //cout<<a[i];}
           // cout<<endl;
        // cout<<s<<"s    ";
                if(s!=0) //若加的将不胡,则下次试其他将时还回原值。
                {
                         for(i=0; i<14; i++)
                         a[i]=b[i];
                
                }
               if(s==0)
                {
                   flat=1;
                   break;
                }
   }
          if(flat)  cout<<"恭喜您!已胡牌!"<<endl;
          else     cout<<"对不起!不能胡牌!"<<endl;
  
    getchar();
    return 0;
}

有兴趣的朋友试下看有没有问题,谢谢 。


[ 本帖最后由 qunxingw 于 2013-1-17 15:39 编辑 ]

www.qunxingw.wang
2013-01-16 12:30
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:70 
自己也写了一个,穷举的,也不知道对不对
程序代码:
#include <math.h>
#include <stdio.h>
#include <string.h>

#define Copy(a, b) memcpy((void *)a, (void *)b, 40)

int change(int *a, int flag[], int m)
{    //依据flag数组和 m值将 a处理(减 3)
    int n = 0;

    if (m & 1)    a[flag[1]] -= 3, ++n;
    if (m & 2)    a[flag[2]] -= 3, ++n;
    if (m & 4)    a[flag[3]] -= 3, ++n;
    if (m & 8)    a[flag[4]] -= 3, ++n;

    return n;
}
int find(int *a)
{    //找到 3张连续的牌,都标记,并返回真值
    for (int i = 1;i < 7;++i)
        if (a[i] && a[i+1] && a[i+2])
        {
            --a[i];--a[i+1];--a[i+2];
            return 1;
        }

    return 0;
}
int main()
{
    int i, j, m, n, flag = 0;
//  int a[10] = {0, 2, 1, 2, 2, 1, 2, 0, 2, 2};
//  int a[10] = {0, 2, 1, 2, 2, 1, 3, 0, 0, 3};
    int a[10] = {0, 3, 0, 2, 2, 2, 2, 0, 0, 3};    //a[i]存储 牌号 i的个数
    int b[10], c[10], temp1[5] = {0}, temp2[11] = {0};

    for (i = 1;i < 10;++i)
    {
        temp1[0] += a[i] >= 3;                    //temp1[0]为牌数不小于 3的个数
        if (temp1[0] && !temp1[temp1[0]])
            temp1[temp1[0]] = i;                //将不小于 3的牌数存储到temp1中
    }

    for (i = (int)pow(2, temp1[0]);i;--i)    //所有牌数不小于 3的共有 i种组合
    {
        Copy(b, a);
        m = change(b, temp1, i-1);            //m表示已标记为 3个相同 的个数
   
        for (j = 1;j < 10;++j)
        {
            temp2[0] += b[j] >= 2;                //同上,此时temp2存储不小于 2的牌数
            if (temp2[0] && !temp2[temp2[0]])
                temp2[temp2[0]] = j;
        }

        for (j = temp2[0];j;--j)
        {
            Copy(c, b);c[temp2[j]] -= 2;

            n = 0;while (find(c))    ++n;

            if (4 == m+n){flag = 1;break;}
        }
   
        if (flag)
        {
            puts("YES!");break;
        }
    }
    return 0;
}


[ 本帖最后由 azzbcc 于 2013-1-16 13:30 编辑 ]


[fly]存在即是合理[/fly]
2013-01-16 13:27
快速回复:麻将胡牌算法
数据加载中...
 
   



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

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