Sicily 1256. Bingo!

做这道题的时候,数据是12S1A,看完题目后觉得是因为这道题太长又晦涩,而又缺乏足够详细的说明,所以问津者寥寥,所以就放手一试,没想到还真是能AC。

题目意思是关于一个Bingo的游戏,首先给出7个数字,前5个数字分别表示每个对应列已经出现了的数字个数,第6个数字(X)表示pattern的数目,第7个数字(Y)表示winning pattern需要由X个pattern中的Y个组合而成,然后给出X个pattern。我们的任务就是求出至少还需要出现多少个数字,才能够Bingo(即组合出winning pattern)。

我的方法是,在X个pattern中选出Y个,逐一组合出所有的CYX个winning pattern,然后分析至少(这种情况下下,我们希望已经出现了的数字都出现在需要的地方,才能够达到至少这一界限)还需要多少个数字才能够Bingo,将这些结果中最少的那个输出即可。

Run Time: 0.05sec

Run Memory: 304KB

Code Length: 1431Bytes

Submit Time: 2012-02-16 21:25:47

// Problem#: 1256
// Submission#: 1211213
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <string>
using namespace std;

int bingo[ 5 ], X, Y, fewest;
char patterns[ 19 ][ 26 ];

string combine( const string& s1, char s2[] );
void analyse( const string& s );
void choose( int m, int n, string s );

int main()
{
    int n;
    int i, j;

    scanf( "%d", &n );
    while ( n-- ) {
        scanf( "%d%d%d%d%d%d%d", &bingo[ 0 ], &bingo[ 1 ], &bingo[ 2 ], &bingo[ 3 ], &bingo[ 4 ], &X, &Y );
        for ( i = 0; i < 5; i++ ) {
            for ( j = 0; j < X; j++ )
                scanf( "%s", &patterns[ j ][ 5 * i ] );
        }

        fewest = 25;
        choose( 0, 0, string( 25, 'O' ) );
        printf( "%d\n", fewest );
    }

    return 0;

}


string combine( const string& s1, char s2[] ) {
    string r = string( 25, 'O' );
    for ( int i = 0; i < 25; i++ )
        r[ i ] = ( s1[ i ] == 'X' || s2[ i ] == 'X' ? 'X': 'O' );
    r[ 12 ] = 'O';
    return r;
}

void analyse( const string& s ) {
    int i, need[ 5 ] = { 0 }, sum = 0;
    for ( i = 0; i < 25; i++ ) {
        if ( s[ i ] == 'X' )
            need[ i % 5 ]++;
    }
    for ( i = 0; i < 5; i++ )
        sum += max( 0, need[ i ] - bingo[ i ] );
    if ( sum < fewest )
        fewest = sum;
}

void choose( int m, int n, string s ) {
    if ( n == Y )
        analyse( s );
    else if ( Y - n <= X - m ) {
        for ( int i = m; i < X; i++ )
            choose( i + 1, n + 1, combine( s, patterns[ i ] ) );
    }
}                                 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值