zoukankan      html  css  js  c++  java
  • 洛谷P1263 宫廷守卫

    P1263 宫廷守卫

    题目描述

    从前有一个王国,这个王国的城堡是一个矩形,被分为M×N个方格。一些方格是墙,而另一些是空地。这个王国的国王在城堡里设了一些陷阱,每个陷阱占据一块空地。

    一天,国王决定在城堡里布置守卫,他希望安排尽量多的守卫。守卫们都是经过严格训练的,所以一旦他们发现同行或同列中有人的话,他们立即向那人射 击。因此,国王希望能够合理地布置守卫,使他们互相之间不能看见,这样他们就不可能互相射击了。守卫们只能被布置在空地上,不能被布置在陷阱或墙上,且一 块空地只能布置一个守卫。如果两个守卫在同一行或同一列,并且他们之间没有墙的话,他们就能互相看见。(守卫就像象棋里的车一样)

    你的任务是写一个程序,根据给定的城堡,计算最多可布置多少个守卫,并设计出布置的方案。

    输入输出格式

    输入格式:

    第一行两个整数M和N(1≤M,N≤200),表示城堡的规模。

    接下来M行N列的整数,描述的是城堡的地形。第i行j列的数用ai,j表示。

    ai,j=0,表示方格[i,j]是一块空地;

    ai,j=1,表示方格[i,j]是一个陷阱;

    ai,j=2,表示方格[i,j]是墙。

    输出格式:

    第一行一个整数K,表示最多可布置K个守卫。

    此后K行,每行两个整数xi和yi,描述一个守卫的位置。

    输入输出样例

    输入样例#1:
    3 4
    2 0 0 0
    2 2 2 1
    0 1 0 2
    
    输出样例#1:
    2
    1 2
    3 3
    

    说明

    样例数据如图5-2(黑色方格为墙,白色方格为空地,圆圈为陷阱,G表示守卫)

    由@zhouyonglong提供SPJ

    【题解】

    空间开到2000疯狂TLE,开到3000T的更多,然后改成200

    A了

    我******

    二分图最大匹配。把行列的01连通块标号,每个0都是连接行列的边

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <algorithm>
      6 
      7 inline void read(int &x)
      8 {
      9     x = 0;char ch = getchar(), c = ch;
     10     while(ch < '0' || ch > '9')c = ch, ch = getchar();
     11     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     12     if(c == '-')x = -x;
     13 }
     14  
     15 const int MAXN = 200 + 10;
     16 
     17 int gg[MAXN][MAXN];
     18 int lk[MAXN * MAXN], b[MAXN * MAXN], g[MAXN][MAXN], r, c, n, m, tmp, line[MAXN][MAXN], row[MAXN][MAXN]; 
     19 
     20 struct Edge
     21 {
     22     int u,v,next;
     23     Edge(int _u, int _v, int _next){u = _u;v = _v;next = _next;}
     24     Edge(){}
     25 }edge[MAXN * MAXN];
     26 int head[MAXN * MAXN],cnt;
     27 void insert(int a, int b)
     28 {
     29     edge[++cnt] = Edge(a,b,head[a]);
     30     head[a] = cnt;
     31 }
     32 
     33 int dfs(int u)
     34 {
     35     for(register int pos = head[u];pos;pos = edge[pos].next)
     36     {
     37         int v = edge[pos].v;
     38         if(!b[v])
     39         {
     40             b[v] = 1;
     41             if(lk[v] == -1 || dfs(lk[v]))
     42             {
     43                 lk[v] = u;
     44                 return 1;
     45             }
     46         }
     47     }
     48     return 0;
     49 }
     50 
     51 int xiongyali()
     52 {
     53     int ans = 0;
     54     memset(lk, -1, sizeof(lk));
     55     for(register int i = 1;i <= n;++ i)
     56     {
     57         memset(b, 0, sizeof(b));
     58         ans += dfs(i);
     59     }
     60     return ans;
     61 } 
     62 
     63 int main() 
     64 {
     65     read(r), read(c);
     66     register int i,j;
     67     for(i = 1;i <= r;++ i)
     68         for(j = 1;j <= c;++ j)
     69             read(gg[i][j]);
     70     register int tot = 0;
     71     for(i = 1;i <= r;++ i)
     72         for(j = 1;j <= c;++ j)
     73             if(gg[i][j] != 2)
     74             {
     75                 ++ tot;
     76                 while(gg[i][j] != 2 && j <= c)row[i][j] = tot,++ j;
     77             }
     78     n = tot;
     79     tot = 0;
     80     for(j = 1;j <= c;++ j)
     81         for(i = 1;i <= r;++ i)
     82             if(gg[i][j] != 2)
     83             {
     84                 ++ tot;
     85                 while(gg[i][j] != 2 && i <= r)line[i][j] = tot, ++ i;
     86             }
     87     m = tot;
     88     for(i = 1;i <= r;++ i)
     89         for(j = 1;j <= c;++ j)
     90             if(gg[i][j] == 0)
     91                 insert(row[i][j], line[i][j]);
     92     printf("%d
    ", xiongyali());
     93     for(register int k = 1;k <= m;++ k)
     94     {
     95         int flag = 0;
     96         if(lk[k] != -1)
     97         {
     98             for(i = 1;i <= r;++ i)
     99             {
    100                 for(j = 1;j <= c;++ j)
    101                 {
    102                     if(row[i][j] == lk[k] && line[i][j] == k && gg[i][j] == 0)
    103                     {
    104                         printf("%d %d
    ", i, j);
    105                         flag = 1;
    106                         break;
    107                     }
    108                 }
    109                 if(flag)break;
    110             }
    111         }
    112     }
    113     return 0;
    114 }
    洛谷P1263
  • 相关阅读:
    csuoj 1391: Boiling Vegetables
    csuoj 1392: Number Trick
    nyist 78 圈水池
    1393: Robert Hood 旋转卡壳 凸包
    模板 旋转卡壳 凸包
    模板 凸包 旋转卡壳
    ASP.NET Web API2返回值处理流程
    DependencyInjection源码解读之ServiceProvider
    深入研究EF Core AddDbContext 引起的内存泄露的原因
    私有云方案——利用阿里云云解析实现DDNS
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7572708.html
Copyright © 2011-2022 走看看