ACM/NCPC2016 C Card Hand Sorting(upc 3028)

题目描述
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

懒人又来更博了。

题意:
有一重扑克(没有大小王)总共52张。其中有♣♥♦♠四种花色,还有2-A 这13种rank。让你先把花色相同的聚集在一起(四个花色顺序任意),每个花色里再按rank递增或递减排序。
给你一串扑克,让你移动(选择一张牌将它放在任意位置)最少数量的牌,使当前扑克有序(指符合上面所说的排序方案)。最后输出移动的扑克数量。

思路

  1. 四个花色的顺序有4!=24种
  2. 每个花色的升序或降序又有2^4=16种
  3. 总共有24*16种可以的顺序。枚举这些顺序,找到当前扑克按此顺序最大的不用移动的数量(即按当前枚举顺序的最大上升子序列)。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
const ll mod=1e9+7;
ll qpow(ll x,ll y){ll ans=1;while(y){if(y%2) ans=ans*x%mod; x=x*x%mod;y/=2;}return ans;}
char s[55][3];
int order[4]={0,1,2,3};
char suit[4]={'s','h','d','c'};
int key[4];
int dp[55]={0};
char cards[13]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
int cmp(char x[3],char y[3],int order[4],int key[4]){

    for(int i=0;i<4;i++)
    {
        if(suit[order[i]]==x[1]&&suit[order[i]]==y[1]){
            int o=key[order[i]];
            if(o==0){//降序
                for(int j=0;j<13;j++){
                    if(x[0]==cards[j]){
                        return 1;
                    }
                    if(y[0]==cards[j]) return -1;
                }
            }
            else{//升序
                for(int j=0;j<13;j++){
                    if(x[0]==cards[j]){
                        return -1;
                    }
                    if(y[0]==cards[j]) return 1;
                }
            }
        }
        else if(suit[order[i]]==x[1])
        {
            return -1;
        }
        else if(suit[order[i]]==y[1]) return 1;
    }
    return 1;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s[i]);
    }
    int Max=0;
    do{
        int t=1<<4;
        for(int i=0;i<t;i++){
            int temp=i;
            for(int j=0;j<4;j++){
                key[j]=temp%2;//0降序,1升序
                temp/=2;
            }
            memset(dp,0,sizeof(dp));
            for(int k=1;k<=n;k++)
            {
                dp[k]=1;
                for(int j=1;j<k;j++){
                    if(cmp(s[j],s[k],order,key)<0&&dp[k]<dp[j]+1)
                        dp[k]=dp[j]+1;
                }
            }
            for(int i=1;i<=n;i++)
            Max=max(Max,dp[i]);
        }
    }while(next_permutation(order,order+4));//懒得直接用了全排列函数求了四个花色的顺序
    cout<<n-Max<<endl;
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值