zoukankan      html  css  js  c++  java
  • HDU1045

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045

    解题思路:

      首先,这题的数据范围很小,可以暴搜,略过不表。此处主要讲二分匹配作法。

      思路来源于网络。

      对于同一行上没有石头相隔的相连格子,我们将其编成一个号,得到一个号码集合X;同一列上没有石头相隔的相连格子也编成一个号,得到另一个号码集合Y。X,Y中的每个号码就代表某一个或者几个格子,如果X中的一个号码对应的格子和Y中的一个号码对应的格子有重叠,那么就记这两个号码相匹配。最后只要求出X和Y的最大匹配数即可得出答案。

      

      图片来源于:http://blog.csdn.net/job_yi/article/details/10172925

    AC代码:

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 char Map[5][5];
     6 int x[5][5],y[5][5];
     7 bool link[20][20],vis[20];
     8 int y_x[20];
     9 int n;
    10 int xi,yi;
    11 bool finds(int x){
    12     for(int i=1;i<=yi;i++){
    13         if(link[x][i]&&!vis[i]){
    14             vis[i]=true;
    15             if(y_x[i]==0||finds(y_x[i])){
    16                 y_x[i]=x;
    17                 return true;
    18             }
    19         }
    20     }
    21     return false;
    22 }
    23 int main(){
    24    while(scanf("%d",&n)==1&&n){
    25         memset(y_x,0,sizeof(y_x));
    26         memset(link,0,sizeof(link));
    27         memset(x,0,sizeof(x));
    28         memset(y,0,sizeof(y));
    29         for(int i=0;i<n;i++)    scanf("%s",Map[i]);
    30         xi=yi=0;
    31         bool used=true;
    32         for(int i=0;i<n;i++){
    33             if(used){
    34                 xi++;  used=false;
    35             }
    36             for(int j=0;j<n;j++){
    37                 if(Map[i][j]=='X'&&used){
    38                     used=false;
    39                     xi++;
    40                 }
    41                 else if(Map[i][j]=='.'){
    42                     x[i][j]=xi;    used=true;
    43                 }
    44             }
    45             if(i==n-1&&!used)   xi--;
    46         }
    47         used=true;
    48         for(int j=0;j<n;j++){
    49             if(used){
    50                 yi++;   used=false;
    51             }
    52             for(int i=0;i<n;i++){
    53                 if(Map[i][j]=='X'&&used){
    54                     yi++;  used=false;
    55                 }
    56                 else if(Map[i][j]=='.'){
    57                     y[i][j]=yi;    used=true;
    58                 }
    59             }
    60             if(j==n-1&&!used)   yi--;
    61         }
    62         for(int i=0;i<n;i++){
    63             for(int j=0;j<n;j++){
    64                 link[x[i][j]][y[i][j]]=true;
    65             }
    66         }
    67         int ans=0;
    68         for(int i=1;i<=xi;i++){
    69             memset(vis,0,sizeof(vis));
    70             if(finds(i))    ans++;
    71         }
    72         printf("%d
    ",ans);
    73    }
    74     return 0;
    75 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    [题解]Magic Line-计算几何(2019牛客多校第三场H题)
    [题解]Crazy Binary String-前缀和(2019牛客多校第三场B题)
    [数论]快速幂取模
    [模板]大整数乘法——累加型
    [动态规划] 最大子段和问题
    2073
    17-2-24-D
    17-1-31-C
    2032
    1992
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7445836.html
Copyright © 2011-2022 走看看