HDU 1528 Card Game Cheater (二分图求最大匹配)

题意:

Adam 和 Eve,每人抽 n ( n <= 26 ) 张牌,然后分别把 n 张牌一一对应比较,每组牌大的一方得 1 分,

假设Eve作弊(知道双方牌的信息),给出双方所抽牌的信息,求如果Eve采用最优策略能得多少分。

牌的比较规则:

  1. 首先比较两张牌的数值,数值大的牌就大,不用继续比较,如果数值相同则进行 2.
  2. 数值相同的情况下比较花色,大小顺序依次是 红桃 > 黑桃 > 梅花 > 方片。

构图:

Adam 和 Eve 的每张牌都看作一个点,两者的牌之间两两比较,

如果 Eve 的牌比 Adam 大,则 Eve 的当前牌到 Adam 的当前牌有一条路径,

匈牙利算法求出所得图的最大匹配数就行


Source Code:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 30;

struct cards
{
    int num;
    int seq;
};

cards adam[maxn];
cards eve[maxn];

int n;
int nextpt[maxn];
int mp[maxn][maxn];
bool vis[maxn];

char evecards[maxn][3];
char adamcards[maxn][3];

bool dfs( int s )
{
    for( int i = 1; i <= n; i++ )
    {
        if( !vis[i] && mp[s][i] != 0 )
        {
            vis[i] = 1;
            if( nextpt[i] == -1 || dfs( nextpt[i] ) )
            {
                nextpt[i] = s;
                return true;
            }
        }
    }
    return false;
}

void init()
{
    memset( nextpt, -1, sizeof( nextpt ) );
    memset( mp, 0, sizeof( mp ) );
}

void ch_switch( char a[], bool flag, int ind )
{
    if( flag == 0 )
    {
        if( a[0] >= '0' && a[0] <= '9' )
            adam[ind].num = (int)( a[0] - '0' );
        else if( a[0] == 'T' )
            adam[ind].num = 10;
        else if( a[0] == 'J' )
            adam[ind].num = 11;
        else if( a[0] == 'Q' )
            adam[ind].num = 12;
        else if( a[0] == 'K' )
            adam[ind].num = 13;
        else if( a[0] == 'A' )
            adam[ind].num = 14;

        if( a[1] == 'H' )   adam[ind].seq = 4;
        else if( a[1] == 'S' )  adam[ind].seq = 3;
        else if( a[1] == 'D' )  adam[ind].seq = 2;
        else if( a[1] == 'C' )  adam[ind].seq = 1;
    }

    else if( flag == 1 )
    {
        if( a[0] >= '0' && a[0] <= '9' )
            eve[ind].num = (int)( a[0] - '0' );
        else if( a[0] == 'T' )
            eve[ind].num = 10;
        else if( a[0] == 'J' )
            eve[ind].num = 11;
        else if( a[0] == 'Q' )
            eve[ind].num = 12;
        else if( a[0] == 'K' )
            eve[ind].num = 13;
        else if( a[0] == 'A' )
            eve[ind].num = 14;

        if( a[1] == 'H' )   eve[ind].seq = 4;
        else if( a[1] == 'S' )  eve[ind].seq = 3;
        else if( a[1] == 'D' )  eve[ind].seq = 2;
        else if( a[1] == 'C' )  eve[ind].seq = 1;
    }
}

int main()
{
    int cas;
    char ch[3];

    scanf( "%d", &cas );
    while( cas-- )
    {
        init();

        scanf( "%d", &n );

        for( int i = 1; i <= n; i++ )
        {
            scanf( "%s", ch );
            ch_switch( ch, 0, i );
        }

        for( int i = 1; i <= n; i++ )
        {
            scanf( "%s", ch );
            ch_switch( ch, 1, i );
        }

        for( int i = 1; i <= n; i++ )
        {
            for( int j = 1; j <= n; j++ )
            {
                if( eve[i].num > adam[j].num )
                    mp[i][j] = 1;
                else if( eve[i].num == adam[j].num )
                {
                    if( eve[i].seq > adam[j].seq )
                        mp[i][j] = 1;
                }
            }
        }

        int ans = 0;
        for( int i = 1; i <= n; i++ )
        {
            memset( vis, 0, sizeof( vis ) );
            if( dfs( i ) )
                ans++;
        }

        printf( "%d\n", ans );
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值