coreBugZJ

此 blog 已弃。

EOJ 1864 Playing With Cubes

  1/*
  2EOJ 1864 Playing With Cubes
  3
  4
  5----问题描述:
  6
  7Children are used to playing with special cubes with letters written on the cubes' faces.
  8The goal of the game is to compose words using such cubes.
  9If you want to compose the word "DOG", you must find 3 cubes, one containing the letter 'D',
 10        one containing the letter 'O', and one containing the letter 'G',
 11        and orient them so the proper letters are facing upward.
 12You are also given a some words, 
 13        each element of which contains a word that you would like to spell out using the cubes.
 14
 15
 16----输入:
 17
 18There are several test cases,
 19each test case begins with two numbers N(1<=N<=50) and M(1<=M<=50).
 20the second line contains N string,the i-th string shows the uppercase letters(between 2 and 50,inclusive) on the i-th cube.
 21The third line contains the M words.Each element of words will contain between 2 and 50 uppercase letters, inclusive.
 22
 23
 24----输出:
 25
 26Output the words' number that can be composed using the given cubes in ascending order.
 27If no words' number that can be composed output -1.
 28
 29
 30----样例输入:
 31
 325 3
 33ABCDEF DEFGHI OPQRST ZZZZZZ YYYYYY
 34CAT DOG PIZZA
 356 7
 36ABCDEF DEFGHI OPQRST MNZLSA QEIOGH IARJGS
 37DOG CAT MOUSE BIRD CHICKEN PIG ANIMAL
 38
 39
 40----样例输出:
 41
 421
 430 1 3 5
 44
 45
 46----分析:
 47
 48对每个 word 建立二分图模型,
 49一边 x[0], x[1],  x[n-1] 分别对应 word 中的每个字母,
 50一边 y[0], y[1],  y[m-1] 分别对应每个 cube ,
 51若字母 x[i] 包含于 cube y[j] 中,则 x[i] 与 y[j] 连一条边,
 52然后求出此二分图最大匹配,若与 word 中字母个数相同,则输出此 word 编号。
 53
 54求二分图最大匹配使用匈牙利算法。
 55
 56
 57*/

 58
 59
 60#include <stdio.h>
 61#include <string.h>
 62
 63#define  L  59
 64
 65
 66/* 匈牙利算法 begin */
 67
 68int n;             /* 一边 x[0], x[1],  x[n-1] */
 69int m;             /* 一边 y[0], y[1],  y[m-1] */
 70int adj[ L ][ L ]; /* adj[i][j] != 0  表示 x[i] 与 y[j] 有边 */
 71int res[ L ];      /* res[j]    != -1 表示当前与 y[j] 匹配的点为 x[res[j]] */
 72int sta[ L ];      /* sta[j]    != 0  表示 y[j] 在可增广路中 */
 73
 74        /* 0 != find 表示找到可增广路 */
 75int find( int i ) {
 76        int j;
 77        for ( j = 0; j < m; ++j ) {
 78                if ( adj[ i ][ j ] && (! sta[ j ]) ) {
 79                        sta[ j ] = 1;
 80                        if ( (-1 == res[ j ]) || (find(res[j])) ) {
 81                                res[ j ] = i;
 82                                return 1;
 83                        }

 84                }

 85        }

 86        return 0;
 87}

 88
 89        /* 求最大匹配 */
 90int maxMatch() {
 91        int i, ans = 0;
 92        memset( res, -1sizeof(res) );
 93        for ( i = 0; i < n; ++i ) {
 94                memset( sta, 0sizeof(sta) );
 95                if ( find(i) ) {
 96                        ++ans;
 97                }

 98        }

 99        return ans;
100}

101
102/* 匈牙利算法 end */
103
104
105int main() {
106        int  tc, tw;
107        char cube[ L ][ L ];
108        char word[ L ];
109        int  ans[ L ], tot;
110        int  i, j, k;
111        while ( 2 == scanf( "%d%d"&tc, &tw ) ) {
112                tot = 0;
113
114                for ( i = 0; i < tc; ++i ) {
115                        scanf( "%s", cube[ i ] );
116                }

117                for ( i = 0; i < tw; ++i ) {
118                        scanf( "%s", word );
119
120                        memset( adj, 0sizeof(adj) );
121                        n = strlen( word );
122                        m = tc;
123                        for ( j = 0; j < n; ++j ) {
124                                for ( k = 0; k < m; ++k ) {
125                                        if ( strchr( cube[ k ], word[ j ] ) != NULL ) {
126                                                adj[ j ][ k ] = 1;
127                                        }

128                                }

129                        }

130
131                        if ( maxMatch() == n ) {
132                                ans[ tot++ ] = i;
133                        }

134                }

135
136                if ( 0 == tot ) {
137                        puts( "-1" );
138                        continue;
139                }

140                printf( "%d", ans[ 0 ] );
141                for ( i = 1; i < tot; ++i ) {
142                        printf( " %d", ans[ i ] );
143                }

144                puts( "" );
145        }

146        return 0;
147}

148

posted on 2012-03-30 22:16 coreBugZJ 阅读(521) 评论(0)  编辑 收藏 引用 所属分类: ACMAlgorithm课内作业


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理