麻将回溯算法(无癞子)

  1 #include <stdio.h>
  2 #include <iostream>
  3 #include <sstream>
  4 #include <cstring>
  5 #include <vector>
  6 
  7 using namespace std;
  8 typedef unsigned char byte;
  9 #define Arrlen(arr) sizeof(arr)/sizeof(arr[0])
 10 
 11 byte arr[11] = {0x01,0x01,0x01,0x02,0x02,0x03,0x03,0x03,0x02,0x04,0x04};
 12 byte arrIndex[5] = {0};
 13 vector<byte> tempArr;
 14 vector<byte> allGroup;
 15 
 16 byte SwitchToCardIndex(byte cbCardData)
 17 {
 18     return cbCardData - 1;
 19 }
 20 
 21 byte SwitchToCardData(byte cbCardIndex)
 22 {
 23     return cbCardIndex + 1;
 24 }
 25 
 26 void GetWeaveItem(byte dep)
 27 {
 28 
 29     //每一种全部组合的区别最终在于将牌的不同,即以将牌的递归遍历为最终的根,可以保证结果的不重复
 30     //遍历每个Index,如果Index兑换成组合后,能否使dep=3,不能则+3还原,去兑换其他的组合
 31     //不区分组成组合的顺序,而是以所有的Index为组合的root节点,枚举所有的组合,并+3还原知道为true
 32     //为true时输出该手牌就OK,注意回溯时的出栈,即缓冲区的回溯
 33 
 34     if (dep == 3 && tempArr.size() == Arrlen(arr)) 
 35     {
 36         cout << "可以和牌" <<endl;
 37 
 38         for(auto itr = tempArr.begin();itr < tempArr.end();itr++)
 39         {
 40             if (itr == tempArr.begin())
 41             {
 42                 cout << (short)*itr;
 43             }
 44             else if (itr == tempArr.begin() + 1)
 45                 cout << (short)*itr << ",";
 46             else
 47                 cout << (short)*itr << " ";
 48             /*allGroup.push_back((short)*itr);*/
 49         }
 50 
 51         cout << endl << endl;
 52     }
 53 
 54     for (int i = 0; i < Arrlen(arrIndex); i++)  
 55     {  
 56         if (arrIndex[i] >= 3)  
 57         {  
 58             arrIndex[i] -= 3; 
 59             tempArr.push_back(SwitchToCardData(i));
 60             tempArr.push_back(SwitchToCardData(i));
 61             tempArr.push_back(SwitchToCardData(i));
 62 
 63             GetWeaveItem(dep+1);
 64 
 65             arrIndex[i] += 3;  
 66             tempArr.pop_back();
 67             tempArr.pop_back();
 68             tempArr.pop_back();
 69 
 70         }  
 71     }
 72 
 73     //最后两张不再需要判断
 74     for (int i = 0; i < Arrlen(arrIndex) - 2; i++)
 75     {  
 76         //arrIndex[4]未报错
 77         if ( i % Arrlen(arrIndex) < (Arrlen(arrIndex) - 2) && arrIndex[i] >= 1 && arrIndex[i + 1] >= 1 && arrIndex[i + 2] >= 1)  
 78         {  
 79             arrIndex[i] --; arrIndex[i + 1] --; arrIndex[i + 2] --; 
 80             tempArr.push_back(SwitchToCardData(i));
 81             tempArr.push_back(SwitchToCardData(i+1));
 82             tempArr.push_back(SwitchToCardData(i+2));
 83 
 84             GetWeaveItem(dep + 1);
 85 
 86             arrIndex[i] ++; arrIndex[i + 1] ++; arrIndex[i + 2] ++;  
 87             tempArr.pop_back();
 88             tempArr.pop_back();
 89             tempArr.pop_back();
 90 
 91         }  
 92     }
 93 
 94 }
 95 
 96 void main()
 97 {
 98     for (byte i=0;i < Arrlen(arr);i++)
 99     {
100         arrIndex[SwitchToCardIndex(arr[i])]++;
101     }
102 
103     string str ="";
104     for (byte i = 0; i < Arrlen(arrIndex); i++)
105     {
106         stringstream stream;
107         stream<<(short)arrIndex[i];
108         str += " "+stream.str();
109     }
110 
111     cout << str <<endl;
112 
113     for (int i = 0; i < Arrlen(arrIndex); i++)  
114     {  
115         if (arrIndex[i] >= 2)//将牌  
116         {  
117             arrIndex[i] -= 2; 
118             tempArr.push_back(SwitchToCardData(i));
119             tempArr.push_back(SwitchToCardData(i));
120 
121             GetWeaveItem(0);
122 
123             arrIndex[i] += 2;
124             tempArr.pop_back();
125             tempArr.pop_back();
126         }
127     }
128 
129     system("pause");
130 }

 

转载于:https://www.cnblogs.com/winways/p/7338526.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值