8.15 I

来源:互联网 发布:java web文件管理系统 编辑:程序博客网 时间:2024/06/17 02:05

I - Hiding Gold

 You are given a 2Dboard where in some cells there are gold. You want to fill the board with 2x 1 dominoes such that all gold are covered. You may use the dominoesvertically or horizontally and the dominoes may overlap. All you have to do isto cover the gold with least number of dominoes.

In the picture,the golden cells denote that the cells contain gold, and the blue ones denotethe 2 x 1 dominoes. The dominoes may overlap, as we alreadysaid, as shown in the picture. In reality the dominoes will cover the full 2x 1 cells; we showed small dominoes just to show how to cover the goldwith 11 dominoes.

Input

Input starts withan integer T (≤ 50), denoting the number of test cases.

Each case startswith a row containing two integers m (1 ≤ m ≤ 20) and n(1 ≤ n ≤ 20) and m * n > 1. Here mrepresentsthe number of rows, and n represents the number of columns.Then there will be m lines, each containing ncharactersfrom the set ['*','o']. A '*' character symbolizesthe cells which contains a gold, whereas an 'o' characterrepresents empty cells.

Output

For each caseprint the case number and the minimum number of dominoes necessary to cover allgold ('*' entries) in the given board.

Sample Input

2

5 8

oo**oooo

*oo*ooo*

******oo

*o*oo*oo

******oo

3 4

**oo

**oo

*oo*

Sample Output

Case 1: 11

Case 2: 4

 

题意:在一个n*m的地图上,有两种字符* o ,其中*代表金矿、o代表空。现在要求你用最少的 1*2 (或者 2*1)的材料盖住所有的金矿。

 

思路:先将题中所给的图每一点用搜索的方式存成一张0,1标记的连通图,用t1记录金矿的个数,然后匈牙利算法计算连通的点的个数存入sum,然后用t1-sum/2计算出需要的最小需要覆盖数。

这道题因为一个变量的重复调用wa了8回,难受。


#include<stdio.h>#include<string.h>int a[500][500],b[500],match[500];char s[100][100];int m,n;int dfs(int s)//匈牙利算法{int i;for(i=1;i<=m*n;i++){if(b[i]==0&&a[s][i]==1){b[i]=1;if(match[i]==-1||dfs(match[i])){match[i]=s;//match[s]=i;return 1;}}}return 0;}int main(){int i,j,k,t,t1,t2,t3,t4=1,x,y,sum;int next[4][2]={{0,1},{1,0},{-1,0},{0,-1}};scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);memset(a,0,sizeof(a));memset(s,0,sizeof(s));memset(match,-1,sizeof(match));for(i=1;i<=n;i++){scanf("%s",s[i]+1);}t1=0;for(i=1;i<=n;i++){for(j=1;j<=m;j++){if(s[i][j]=='*'){t1++;for(k=0;k<=3;k++)//搜索四个方向{x=i+next[k][0];y=j+next[k][1];if(x>n||y>m||x<1||y<1)continue;if(s[x][y]=='*'){a[(i-1)*m+j][(x-1)*m+y]=1;}}}}}sum=0;for(i=1;i<=m*n;i++){memset(b,0,sizeof(b));if(dfs(i))sum++;}printf("Case %d: %d\n",t4++,t1-sum/2);}return 0;}



原创粉丝点击