Card Hand Sorting+枚举 重rank

When dealt cards in the card game Plump it is a good idea to start by sorting the cards in hand by suit and rank. The different suits should be grouped and the ranks should be sorted within each suit. But the order of the suits does not matter and within each suit, the cards may be sorted in either ascending or descending order on rank. It is allowed for some suits to be sorted in ascending order and others in descending order.
Sorting is done by moving one card at a time from its current position to a new position in the hand, at the start, end, or in between two adjacent cards. What is the smallest number of moves required to sort a given hand of cards?

 

输入

The first line of input contains an integer n (1 ≤ n ≤ 52), the number of cards in the hand. The second line contains n pairwise distinct space-separated cards, each represented by two characters. The first character of a card represents the rank and is either a digit from 2 to 9 or
one of the letters T , J , Q , K , and A representing Ten, Jack, Queen, King and Ace, respectively, given here in increasing order. The second character of a card is from the set { s , h , d , c } representing the suits spades ♠, hearts ♥, diamonds ♦, and clubs ♣.

 

输出

Output the minimum number of card moves required to sort the hand as described above.

 

样例输入

7
9d As 2s Qd 2c Jd 8h

 

样例输出

2
#include<bits/stdc++.h>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=505;
int n,ans,a[4]={0,1,2,3};
char p[MAXN][5],s[4]={'s','h','d','c'};
int b[MAXN],d[MAXN];
struct Node{
    int pos,val;
}c[MAXN];

bool cmp1(Node a,Node b){
    return a.val<b.val;
}

bool cmp2(Node a,Node b){
    return a.val>b.val;
}

int get(char ch){
    if(ch>='0'&&ch<='9')return ch-'0';
    if(ch=='A')return 14;
    if(ch=='T')return 10;
    if(ch=='J')return 11;
    if(ch=='Q')return 12;
    if(ch=='K')return 13;
}

void work(int x){
    int rk=0;
    for(int i=0;i<4;i++){
        int tot=0;
        for(int j=0;j<n;j++){
            if(p[j][1]==s[a[i]]){
                c[tot].pos=j;c[tot].val=get(p[j][0]);
                tot++;
            }
        }
        if(x&(1<<i))sort(c,c+tot,cmp1);
        else sort(c,c+tot,cmp2);
        for(int j=0;j<tot;j++){
            b[c[j].pos]=rk++;
        }
    }
    int k=1;
    d[k]=b[0];
    for(int i=1;i<n;i++){
        if(b[i]>d[k])d[++k]=b[i];
        else{
            int l=1,r=k;
            while(l<=r){
                int mid=(l+r)>>1;
                if(b[i]>d[mid])l=mid+1;
                else r=mid-1;
            }
            d[l]=b[i];
        }
    }
    ans=min(ans,n-k);
}

int main() {
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%s",&p[i]);
    ans=INF;
    do{
        for(int i=0;i<(1<<4);i++)work(i);
    }while(next_permutation(a,a+4));
    printf("%d\n",ans);
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值