做这道题的时候,数据是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 ] ) );
}
}