【双向线性扫描+环形队列】亚马逊笔试题:扑克牌比大小

两个4张的扑克牌比较大小:

A可以看成14,JQK对应11 12 13.

有六种牌的类型。

比较麻烦,100+行逻辑才搞定。

 先要读数,并记录各个牌的出现个数:scanf=>buf[] =>a[]=>cntNum[1~4][]

  • 然后判断a[]是哪种类型扑克牌:顺子?豹子?双对?对子?大头?
  • 尤其是判断顺子比较麻烦,有一种特殊情况:注意QKA2也是顺子
    • 判断方法:
    • sort(a,a+4)
    • 考虑顺子的特殊情况
      • 如果a[0]==2,a[3]=A,
        • 那么a[i]从左到右扫描,a[j]从右到左扫描,判断是否a[i]=a[i-1]+1,a[j]=a[j-1]+1,最后i==j则是特殊情况。否则是大头。特殊情况下决定其大小的是a[i]这张牌。把它放到a[3]位置上,后面要用到。
    • 考虑顺子普通情况:递增。

 再判断相同类型的扑克牌的大小。非顺子,从cntNum[4]到cntNum[1]进行比较。顺子只比较a[3]即顺子最后一张牌即可。


#include <iostream>
#include <algorithm>
#include <vector>
#include <stdio.h>
using namespace std;
// #define DEBUG false 
// #define cout if(DEBUG) cout
int cmp(vector<vector<int> >&a,vector<vector<int> >&b,int type){
    switch(type){
        case 1://four
        return a[4][0]-b[4][0];
        case 2://string  ####
        return a[1][3]-b[1][3];
        case 3://one three, one one
        return a[3][0]!=b[3][0]?a[3][0]-b[3][0]:a[1][0]-b[1][0];
        case 4://two pair
        return a[2][1]!=b[2][1]?a[2][1]-b[2][1]:a[2][0]-b[2][0];
        case 5://one pair
        return a[2][0]!=b[2][0]?a[2][0]-b[2][0]:a[1][1]!=b[1][1]?a[1][1]-b[1][1]:a[1][0]-b[1][0];
        case 6:
        return a[1][3]!=b[1][3]?a[1][3]-b[1][3]:a[1][2]!=b[1][2]?a[1][2]-b[1][2]:
               a[1][1]!=b[1][1]?a[1][1]-b[1][1]:a[1][0]-b[1][0];
		default:
		return 0;
    }
}
void init(char buf[],vector<vector<int> > & cntNum,int &type){
    int a[4];
    for(int i=0,j=0;j<=3&&buf[i]!=0;j++){
        switch(buf[i]){
            case 'A':
                a[j]=14;i+=2;break;
            case 'J':
                a[j]=11;i+=2;break;
            case 'Q':
                a[j]=12;i+=2;break;
            case 'K':
                a[j]=13;i+=2;break;
            case '1':
                a[j]=10;i+=3;break;
			default:
                a[j]=buf[i]-'0';i+=2;
				break;
        }
    }
    sort(a,a+4);
	// for(int i=0;i<4;i++) cout<<a[i]<<"--";cout<<endl;
    
    int cnt=0,same=0,maxSame=0,lst=-1;
    for(int i=0;i<=4;i++){
        if(i==4||a[i]!=lst){
            if(lst!=-1) cntNum[same].push_back(lst);
            cnt++;
            if(i==4) break;
            lst=a[i];
            same=1;
        }
        else {
            same++;
            maxSame=max(same,maxSame);
        }
    }

    if(cnt==1) type=1;
    else if(cnt==2){
        if(maxSame==2) type=4;
        else type=3;
    }
    else if(cnt==3){
        type=5;
    }
    else{
        type=2;
		if(a[0]==2&&a[3]==14){
			int i=1,j=3;	
			while(i<4&&a[i]==a[i-1]+1) i++;
			while(j>=0&&a[j]==a[j-1]+1) j--;
			if(i!=j) type=6;
			else{
				cntNum[1][3]=a[i-1];
			}
		}
		else{
			int i=1;
			while(i<4){
				if(a[i]!=a[i-1]+1) {
					type=6;
					break;
				}
				i++;
			}
		}
    }
	// cout<<"type:"<<type<<endl;
}
int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */
    vector<vector<int> > as(4,vector<int>());
    vector<vector<int> > bs(4,vector<int>());
    int ta,tb;

	char buf[1000];
	scanf("%s",buf);
	// cout<<buf<<endl;
    init(buf,as,ta);
	scanf("%s",buf);
	// cout<<buf<<endl;
    init(buf,bs,tb);
    
    if(ta!=tb){
        printf("%d\n",ta>tb?-1:1);
    }
    else{
		int s=cmp(as,bs,ta);
        printf("%d\n",s>0?1:s==0?0:-1);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值