【问题描述】
牌只有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
题解
思路
- 1.直接用map存储然后map查询就好了,存储每张牌有几张
- 2.然后查找对应可以压得牌直接满足要求就好了
- 注意:这里遇到了一个有意思得bug,就是
if(m.count(j)) //如果存在才比较,不然就不比较。如果不存在还比较。会自动赋值!
if(m[j]>=temp.length()){//手上有的牌数大于等于需要出的牌数
如果没有m.count()的判断,直接用m[j],他返回的不是0,而是1,也就是说,对于map没有的值,他会默认返回1,并且对其进行赋值,以后也是1
- 注意:
if(j==i+5&&m.count(i+4)){//遍历完成且最后一个满足,就找到了一个答案
出口要判断他的最后一个是否满足
代码
#include<iostream>
#include<string>
#include<map>
using namespace std;
/*****************将str分成数字存储到map***********************/
map<int,int> get_map(string str){
map<int,int> m;
for(int i=0;i<str.length();i++){
m[str[i]-'0']++;
}
return m;
}
/*****************获得1-4张牌的结果字符串**********************/
string get_ans(int num,int length){
string ans="";
for(int i=0;i<length;i++){
ans+=num+'0';
}
return ans;
}
/*****************获得5张牌的顺子字符串************************/
string get_ans2(int num,int length){
string ans="";
for(int i=0;i<length;i++){
ans+=num+i+'0';
}
return ans;
}
int main(){
string str;
cin>>str;//输入牌
map<int,int> m=get_map(str);//获得map
string temp;
while(cin>>temp){
int flag=0; //控制输出yes no
if(temp.length()!=5){
int i=temp[0]-'0';
for(int j=i+1;j<10;j++){
if(m.count(j)) //如果存在才比较,不然就不比较。如果不存在还比较。会自动赋值!
if(m[j]>=temp.length()){//手上有的牌数大于等于需要出的牌数
if(!flag) {
cout<<"YES ";
flag=1;
}
cout<<get_ans(j,temp.length())<<" ";
}
}
}else{//只能用顺子管
for(int i=temp[0]-'0'+1;i<=5;i++){
int j;
for(j=i;j<=i+4;j++){//这里是+4 0 1 2 3 4
if(m.count(j)==0) break;
}
if(j==i+5&&m.count(i+4)){//遍历完成且最后一个满足,就找到了一个答案
if(!flag){
cout<<"YES ";
flag=1;
}
cout<<get_ans2(i,5)<<" ";
}
}
}
if(!flag) cout<<"NO";
cout<<endl;
}
return 0;
}