1.题目
2.开始思路
一开始以为弄个正常的排序数组然后判断即可,后来发现一个判断的大问题,即用数组的话我一开始用的核心判断逻辑是只是判断aaa型和abc型,但是示例2运行的时候发现不对劲了,因为还有abbccd型和aabbcc类型我还没有作判断.由此展开的还可以是嵌套了两个类型或以上的类型,比如abbbbccccddd型,aabbbcccd型等等.....用数组做这些逻辑的话会废非常大的功夫.所以可以另辟蹊径.
先贴上我一开始用数组作的思路
#include <iostream>
using namespace std;
// 快速排序函数
void quick_sort(int arr[], int left, int right) {
if (left >= right) {
return;
}
int pivot = arr[left]; // 选择第一个元素作为基准值
int i = left, j = right;
while (i < j) {
while (i < j && arr[j] >= pivot) {
j--;
}
arr[i] = arr[j];
while (i < j && arr[i] <= pivot) {
i++;
}
arr[j] = arr[i];
}
arr[i] = pivot; // 将基准值放到正确的位置
quick_sort(arr, left, i - 1); // 递归对基准值左侧的子数组进行快速排序
quick_sort(arr, i + 1, right); // 递归对基准值右侧的子数组进行快速排序
}
bool insert(int *pai, int *paiDemo, int new_pai) { // new_pai==1-9
bool add = false;
for (int i = 0; i < 14; i++) {//i have 13
if (pai[i] == new_pai && i + 4 < 13)
if ((pai[i] == pai[i + 1] && pai[i] == pai[i + 2] &&
pai[i] == pai[i + 3]) &&pai[i]==
pai[i + 4]) {
return false;
}
if (pai[i] <= new_pai && i < 13) {
paiDemo[i] = pai[i];
} else {
if (!add && i <= 13) {
paiDemo[i] = new_pai;
add = true;
} else {
paiDemo[i] = pai[i - 1];
}
}
}
return true;
}
int main() {
int pai[14]={1, 1, 1, 1, 2, 2, 3, 3, 5, 6, 7, 8, 9};
// for (int i = 0; i < 14; i++) {
// cin >> pai[i];
// }
quick_sort(pai, 0, 12);
for(int ak=0;ak<14;ak++){
cout<<pai[ak];
}
cout<<endl<<"牌已经有序"<<endl;
//已经排完序的pai
int count=0;
// int j=9;
for (int j = 1; j < 10; j++) { // j为听牌数字 1-9
int paiDemo[14];
if (insert(pai, paiDemo, j)) {
//逻辑coding...
for(int i=0; i<13; i++){// i是将牌下标
if(paiDemo[i]==paiDemo[i+1]&&i+1<=13){
int k=0;//k 是牌下标0-13
bool ak=true;
for( ; k<14; k++){
int index[6];
if(k==i){
k+=1;
continue;
}else if(k+1==i){
if(k+4>=13){
ak=false;
break;
}
index[0]=k;
index[1]=k+3;
index[2]=k+4;
}else if(k+2==i){
if(k+4>=13){
ak=false;
break;
}
index[0]=k;
index[1]=k+1;
index[2]=k+4;
}else{
if(k+2>=13){
ak=false;
break;
}
index[0]=k;
index[1]=k+1;
index[2]=k+2;
}
if(paiDemo[index[0]]==paiDemo[index[1]]&&paiDemo[index[0]]==paiDemo[index[2]]){//如 111型
k=index[2];
}else if(paiDemo[index[0]]==paiDemo[index[1]]-1&&paiDemo[index[1]]==paiDemo[index[2]]-1){//如123型
k=index[2];
}else{
ak=false;
break;
}
}
if(ak){
count++;
break;
}
}
}
}
}
cout<<"this is count "<<count<<endl;
while(1){}
}
// 64 位输出请用 printf("%lld")
3.想到的正确思路
可以自己创建一个关于牌的class,包含增删改查,但是会有点麻烦,于是我把牌的1-9绑定a-i的string类型.就能调用string类型的增删改查了;
核心判断: 首先循环将牌(即雀头),把两个符合的将牌用string类型的erase删去,再循环判断是否有aaa型,有的话就删去循环继续,没有的话去找是否有abc型,有的话就删去循环继续,没有的话都不用找了,直接就不成立.以上两个循环可以确立一种听牌的情况,只要循环每一个听牌情况即可求出本题答案.
#include <iostream>
using namespace std;
class my_arr {
public:
string arr;
my_arr() { arr = ""; }
int change_string_num(string str) {
if (str == "a")
return 1;
else if (str == "b")
return 2;
else if (str == "c")
return 3;
else if (str == "d")
return 4;
else if (str == "e")
return 5;
else if (str == "f")
return 6;
else if (str == "g")
return 7;
else if (str == "h")
return 8;
else if (str == "i")
return 9;
else
return -1;
}
string change_num_string(int num) {
switch (num) {
case 1:
return "a";
case 2:
return "b";
case 3:
return "c";
case 4:
return "d";
case 5:
return "e";
case 6:
return "f";
case 7:
return "g";
case 8:
return "h";
case 9:
return "i";
default:
return "-1";
}
}
void add(int mum) { arr += change_num_string(mum); }
};
// 快速排序函数
void quick_sort(int arr[], int left, int right) {
if (left >= right) {
return;
}
int pivot = arr[left]; // 选择第一个元素作为基准值
int i = left, j = right;
while (i < j) {
while (i < j && arr[j] >= pivot) {
j--;
}
arr[i] = arr[j];
while (i < j && arr[i] <= pivot) {
i++;
}
arr[j] = arr[i];
}
arr[i] = pivot; // 将基准值放到正确的位置
quick_sort(arr, left, i - 1); // 递归对基准值左侧的子数组进行快速排序
quick_sort(arr, i + 1, right); // 递归对基准值右侧的子数组进行快速排序
}
bool insert(int *pai, int *paiDemo, int new_pai) { // new_pai==1-9
bool add = false;
for (int i = 0; i < 14; i++) { // i have 13
if (pai[i] == new_pai && i + 4 < 13)
if (pai[i] == pai[i + 1] && pai[i] == pai[i + 2] && pai[i] == pai[i + 3]) {
return false;
}
if (pai[i] <= new_pai && i < 13) {
paiDemo[i] = pai[i];
} else {
if (!add && i <= 13) {
paiDemo[i] = new_pai;
add = true;
} else {
paiDemo[i] = pai[i - 1];
}
}
}
return true;
}
int main() {
// int pai[14] = {1 ,1 ,1 ,1 ,2 ,2 ,3 ,3 ,5 ,6, 7 ,8 ,9};
int pai[14];
for (int i = 0; i < 14; i++) {
cin >> pai[i];
}
quick_sort(pai, 0, 12);
for (int ak = 0; ak < 14; ak++) {
cout << pai[ak];
}
cout << endl << "牌已经有序" << endl;
//已经排完序的pai
int count = 0;
int count_tin[9];
my_arr *paiArr;
// int j=9;
for (int j = 1; j < 10; j++) { // j为听牌数字 1-9
int paiDemo[14];
if (insert(pai, paiDemo, j)) {
//逻辑coding...
for (int i = 0; i < 13; i++) { // i是将牌下标
paiArr = new my_arr(); //逻辑是对paiArr操作
for (int k = 0; k < 14; k++) {
paiArr->add(paiDemo[k]);
}
if (paiDemo[i] == paiDemo[i + 1] && i + 1 <= 13) {
//把将牌删了
paiArr->arr.erase(i,2);
bool ak = true;
while (1) {
if (paiArr->arr.length() >= 3) {
if (paiArr->arr[0] == paiArr->arr[1] &&
paiArr->arr[0] == paiArr->arr[2]) { //组合刻子
paiArr->arr.erase(0,3);
} else { //组合顺子
string now_str,next2_str;//下一个字母
now_str.push_back( paiArr->arr[0]);
int next = paiArr->change_string_num(now_str)+1; //下一个pai数字
int next_index = paiArr->arr.find(paiArr->change_num_string(next)); //下一个数字下标
if (next_index > 0 && next_index < 14) {
int next2_index =
paiArr->arr.find(paiArr->change_num_string(next + 1));
if (next2_index > next_index && next2_index < 14) {
//有顺子
paiArr->arr.erase(0,1);
paiArr->arr.erase(next_index-1,1);
paiArr->arr.erase(next2_index-2,1);
continue;
}
}
//没有顺子
ak = false;
break;
}
} else {
if (paiArr->arr.length() != 0) {
ak = false;
break;
}else{
break;
}
}
}
if (ak) {
count_tin[count]=j;
count++;
break;
}
}
//跳过相同的将牌
while(paiDemo[i+1]==paiDemo[i]){
i++;
}
}
}
}
for(int aj=0;aj<count;aj++){
cout<<count_tin[aj]<<" ";
}
cout<<endl;
cout << "this is count " << count << endl;
while (1) {
getchar();
}
}
4.总结
耗费时间是一天,主要是需要掌握对string类型的用法和逻辑判断不是用数组而是用string类型.