一、题目
二、解题思路
特别注意多组三张两张组合的情况
具体思路的见代码注释部分
三、代码
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
vector<int>split(string params) {
vector<int>p;
while (params.find(" ") != string::npos) {
int found = params.find(" ");
p.push_back(stoi(params.substr(0, found)));
params = params.substr(found + 1);
}
p.push_back(stoi(params));
return p;
}
bool comp20(vector<int>a, vector<int>b) { //先按出现次数降序,次数相同则字典降序
if (a[1] == b[1]) {
return a[0] > b[0];
}
else {
return a[1] > b[1];
}
}
bool comp201(vector<int>c, vector<int>d) { //直接按从大到小排
return c[0] > d[0];
}
bool comp202(int c, int d) { //直接按从大到小排
return c > d;
}
int main() {
string input_str;
getline(cin, input_str);
vector<int>input_vec = split(input_str);
//key为扑克牌大小,value为数量
map<int, int>input_map;
for (int i = 0; i < input_vec.size(); i++) {
if (input_map.count(input_vec[i])) {
input_map[input_vec[i]]++;
}
else {
input_map[input_vec] = 1;
}
}
vector<int>temp;
vector<vector<int>>temp1;
for (auto x : input_map) {
temp.push_back(x.first);
temp.push_back(x.second);
temp1.push_back(temp);
temp.clear();
}
sort(temp1.begin(), temp1.end(), comp20); //按照value降序排列
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int e = 0;
vector<int>res;
vector<int>res1;
vector<int>res2;
for (int i = 0; i < temp1.size(); i++) {
if (temp1[i][1] == 4) { //最大有四张,直接输出
a++;
for (int j = 0; j < 4; j++) {
res.push_back(temp1[i][0]);
}
for (int j = 0; j < 4; j++) {
res1.push_back(temp1[i][0]);
}
}
else if (temp1[i][1] == 3) {
b++;
for (int j = 0; j < 3; j++) {
res.push_back(temp1[i][0]);
}
}
else if (temp1[i][1] == 2) {
c++;
for (int j = 0; j < 2; j++) {
res.push_back(temp1[i][0]);
}
}
else if (temp1[i][1] == 1) {
d++;
for (int j = 0; j < 1; j++) {
res.push_back(temp1[i][0]);
}
res2.push_back(temp1[i][0]); //同时记录单张的情况
}
}
for (int i = 0; i < a; i++) {
temp1.erase(temp1.begin()); //四张的都放进数组了,故而移除
}
for (int i = 0; i < d; i++) {
temp1.erase(temp1.begin() + temp1.size() - 1); // 单张的都放进数组了,故而移除
}
//此刻的temp1已经只有三张和两张的情况
if (b == 0 || b == 1) { //这种情况不用考虑葫芦,或者说葫芦的32挨着
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
}
else { //有多组三张和两张的情况
while (temp1.size() != 0) {
if (temp1[0][1] == 3) { //防止出现三张的没两张多的情况,只有可能出现三带二才进入下面
for (int j = 0; j < 3; j++) { //先将排序后的前三张放进res1(res1里已有四张的情况)
res1.push_back(temp1[0][0]);
}
temp1.erase(temp1.begin()); //放进后就移除
sort(temp1.begin(), temp1.end(), comp201); //由于要三带二,所以对剩余的不管张数,直接按大小排
if (temp1[0][1] == 3) { //排完后,倘若首位还为三张
for (int j = 0; j < 2; j++) {
res1.push_back(temp1[0][0]); //前两张放进res1
}
res2.push_back(temp1[0][0]); //最后零的一张放进res2(res2里已有最早遍历时单张的情况)
temp1.erase(temp1.begin());//放进后就移除
}
else { //倘若首位为两张
for (int j = 0; j < 2; j++) {
res1.push_back(temp1[0][0]); //那么直接放进res1
}
temp1.erase(temp1.begin());
}
sort(temp1.begin(), temp1.end(), comp20); //找出第一个三带二后,按照原来的逻辑排序
}
else { //已经移除到首位不为三张的情况
for (int j = 0; j < 2; j++) {
res1.push_back(temp1[0][0]); //前两张放进res1
}
temp1.erase(temp1.begin());
}
}
sort(res2.begin(), res2.end(), comp202);
for (int i = 0; i < res2.size(); i++) {
res1.push_back(res2[i]);
}
for (int i = 0; i < res1.size(); i++) {
cout << res1[i] << " ";
}
}
return 0;
}