问题描述】
牌只有1到9,手里拿着已经排好序的牌a,对方出牌b,用程序判断手中牌是否能够压过对方出牌。
规则:出牌牌型有5种
[1]一张 如4 则5…9可压过
[2]两张 如44 则55,66,77,…,99可压过
[3]三张 如444 规则如[2]
[4]四张 如4444 规则如[2]
[5]五张 牌型只有12345 23456 34567 45678 56789五个,后面的比前面的均大。
【输入形式】
输入有多行,第一行代表手中的牌,长度不超过200个数字。接下来的每一行代表每次对方出的牌。
【输出形式】
输出有多行,代表手中的牌是否能压过对方出的牌,压过输出YES, 并列出所有可选项,可选项之间用空格分隔。 否则输出NO。
【样例输入】
17624234556367 33 222 34567
【样例输出】
YES 44 55 66 77 YES 666 NO
思路:用map存储各牌的数量,再根据需要大过牌的长度进行判断,最后利用string的相加进行输出。(string的相加具体见:https://blog.csdn.net/longzaizai_/article/details/120128620)
#include<bits/stdc++.h>//注意:数字字符可以直接比较大小,但是排序时不能用快排
using namespace std;
string getstr(int begin,int len) {
string str="";
for(int i=0; i<len; i++)
str+=begin+'0';//字符也能相加
return str;
}
string getstr2(int begin) {
string str2="";
for(int i=0; i<5; i++)
str2+=i+begin+'0';
return str2;
}
int main() {
string str1;
cin>>str1;//获得手中牌
map<int,int>m;//用来存储牌和牌数
for(int i=0; i<str1.length(); i++) {
m[str1[i]-'0']++;
}
string temp;//要大过的牌
while(cin>>temp) {
int flag=0;//控制输出yes或no
if(temp.length()!=5) {
int s1=temp[0]-'0';
for(int i=s1+1; i<10; i++) {
if(m.count(i)) { //map中如果存在就进行比较
if(m[i]>=temp.length()) {
if(!flag) { //表示第一次输出
flag=1;
cout<<"YES ";
}
cout<<getstr(i,temp.length())<<' ';
}
}
}
} else { //顺子
//获得顺子的第一位数
for(int i=temp[0]-'0'+1; i<=5; i++) {
int j;
for(j=i; j<=i+4; j++) {
if(m.count(j)==0)break;//如果不连贯,就退出循环
}
if(j==i+5) { //j+i这一句说明有连贯的顺子
if(flag==0) {
flag=1;
cout<<"YES ";
}
cout<<getstr2(i)<<' ';
}
}
}
if(flag==0) { //说明没有可以大过的牌
cout<<"NO";
}
cout<<endl;
}
return 0;
}