首页 > 其他分享 >AcWing 1359. 洛谷P1457 城堡

AcWing 1359. 洛谷P1457 城堡

时间:2022-12-31 17:35:03浏览次数:49  
标签:sz 1359 洛谷 area int max P1457 ++ qquad

解题思路

\(\qquad\)这道题目是需要维护各种连通块信息的,所以这里我们可以也用并查集维护。这题我们如果注意一点细节,也是可以让代码变得很简洁的:

\(\qquad\quad 1.\)这道题的输入自带状态压缩,如果一个数\(a \& 1=1\),那么这个数代表这个格子有西面的墙,东南北也是相似。

\(\qquad\quad 2.\)当移除方法不唯一时,优先选择对应方格区域更靠西的墙
\(\qquad\qquad\)如果仍存在多解,选择对应方格区域更靠南的墙。
\(\qquad\qquad\)在此基础上,还存在多解,那么优先选择北面的墙。
$\qquad\quad\ \ \ $这就启发着我们对于移除的时候优先从西面枚举,再枚举南面,由于格子都是黏在一起的(某个格子的南墙是它下面那个格子的北墙)所以我们只需要枚举北面和东面(因为条件3对北面有限制)的墙就可以了。

可爱的并查集

初始化不可以把存连通块大小的数组\(memset\)成1,因为是按照字节赋值的

代码

#include <iostream>
#include <cstring>

using namespace std;

const int N = 55, M = N * N;
int p[M], n, m, g[N][N], sz[M];

int find(int x) 
{
    if (x == p[x]) return x;
    return p[x] = find(p[x]);
}

int main() 
{
    scanf("%d%d", &m, &n);
    
    for (int i = 0; i < n; i ++ ) 
        for (int j = 0; j < m; j ++ ) 
            scanf("%d", &g[i][j]);
            
    for (int i = 0; i < n * m; i ++ ) p[i] = i, sz[i] = 1;
    
    int cnt = n * m, max_area = 1; 
    int dx[] = {-1, 0}, dy[] = {0, 1}, dw[] = {2, 4};
    
    for (int i = 0; i < n; i ++ ) 
        for (int j = 0; j < m; j ++ ) 
            for (int k = 0; k < 2; k ++ ) 
            {
                if (g[i][j] & dw[k]) continue ;
                int x = i + dx[k], y = j + dy[k];
                if (x < 0 || x >= n || y < 0 || y >= m) continue ;
                
                int u = i * m + j, v = x * m + y;
                u = find(u), v = find(v);
                if (u != v) {
                    p[u] = v, sz[v] += sz[u];
                    -- cnt, max_area = max(max_area, sz[v]);
                }
            }
            
    printf("%d\n%d\n", cnt, max_area);
    
    max_area = 0;
    int rx, ry, rw;
    for (int j = 0; j < m; j ++ ) 
        for (int i = n - 1; ~i; i -- ) 
            for (int k = 0; k < 2; k ++ ) 
            {
                if (!g[i][j] & dw[k]) continue ;
                int x = i + dx[k], y = j + dy[k];
                if (x < 0 || x >= n || y < 0 || y >= m) continue ;
                
                int u = i * m + j, v = x * m + y;
                u = find(u), v = find(v);
                if (u != v) {
                    int ar = sz[v] + sz[u];
                    if (ar > max_area) max_area = ar, rx = i + 1, ry = j + 1, rw = k;
                }
            }
            
    printf("%d\n%d %d %c\n", max_area, rx, ry, (rw ? 'E' : 'N'));
    
    return 0;
}

标签:sz,1359,洛谷,area,int,max,P1457,++,qquad
From: https://www.cnblogs.com/StkOvflow/p/17017003.html

相关文章

  • 洛谷P2296 [NOIP2014 提高组] 寻找道路 题解
    题目链接:P2296[NOIP2014提高组]寻找道路-洛谷|计算机科学教育新生态(luogu.com.cn)好了,话不多说上代码:1#include<bits/stdc++.h>2usingnamespacestd;3......
  • 洛谷P8868 [NOIP2022] 比赛
    离线所有询问(按右端点排序),然后枚举右端点\(r\)。记\(X_l\)为\(a\)在区间\([l,r]\)中的最大值,\(Y_l\)为\(b\)在区间\([l,r]\)中的最大值。在枚举的过程中,对......
  • 洛谷 P5363 / LOJ #3114 「SDOI2019」移动金币
    洛谷传送门LOJ传送门不错的博弈+计数。不难发现题中的游戏是阶梯Nim的变体。若设\(a_i\)为第\(i\)枚金币的位置,令\(\foralli\in[2,m],\b_i=a_i-a_{i-......
  • 洛谷 SP11414 / SPOJ COT3 Combat on a tree
    洛谷传送门SPOJ传送门考虑计算出以\(u\)为根的子树的\(\text{SG}\)值。在\(u\)子树内选择一个白点\(w\),将\(w\tou\)上的所有点删去,原树会变成森林,\(\text{S......
  • 洛谷P4146 序列终结者 题解 splay tree
    题目链接:https://www.luogu.com.cn/problem/P4146题目大意:支持:区间更新(+x)区间翻转区间查询(最大值)解题思路:几乎和AcWing2437.Splay这题一模一样。示例程序:#inc......
  • 洛谷 P5721 【入门3】循环结构
    P5721【深基4.例6】数字直角三角形1.题目描述给出 n,请输出一个直角边长度是 n 的数字直角三角形。所有数字都是 2 位组成的,如果没有 2 位则加上前导 00。2.输......
  • AcWing1134/洛谷P1144 最短路计数
    AcWing传送门洛谷传送门题目大意\(\qquad\)给一个无向图,边权都是\(1\),求出以\(1\)为源点,到各个点(\(1\simn\))的最短路数量解题思路\(\qquad\)边权都是\(1\)的图中最......
  • 洛谷P2024 [NOI2001] 食物链
    slojP2577.食物链题目大意说实话,我做对了之后都还是有点懵语文不好都这么招歧视了吗,我太难了三类动物A,B,C,A吃B,B吃C,C吃A。给出若干关系,判断第几个关系是错误的......
  • 洛谷P1196 [NOI2002] 银河英雄传说
    slojP2577.食物链题目大意一个序列初始编号为1,2,3,,,30000有2个操作:mij合并第i列和第j列,将第i列头部接到第j列尾部cIj询问i号和j号之间的数量,若......
  • Solution -「COCI 2009-2010」「洛谷 P8076」RESTORAN
    \(\mathscr{Description}\)  Link.  给定一个含\(n\)个点\(m\)条边的简单图,求一种边二染色方案,使得所有\(\deg\ge2\)的结点都邻接于两种颜色的边.  \(n......