【每日一题】5月12日模拟战役

模拟战役

https://ac.nowcoder.com/acm/problem/14698

终于出现了一个我会写的题QAQ

题意

题意很简单,就是有n列,上面四列是a的,下面四列是b的,每个人都有几架炮,对轰嘛,就是你打我我打你,现在a开挂,有全图视野,b不知道,所以a先手,b被打了之后就会有a开炮的那架炮的视野(所以b就会果断反击),然后呢如果被打到了大炮,大炮就会炸,炸的话会把周围的炮也炸了,题意中波及的范围周围八个反向,然后问a能不能打过,如果能打过输出最多还剩多少炮,不能输出-1。

输入描述

第1行输入一个整数m,表示地图的宽度。
第2-5行,每行输入一串长度为m的字符串,代表司机的大炮部署。(大炮为"*"号,空地为“.”号)
第6-9行,每行输入一串长度为m的字符串,代表齐齐的大炮部署。(大炮为"*"号,空地为“.”号)
数据保证:0<m≤100

输出描述

输出一行,一个整数。代表摧毁所有司机的大炮后最多保留几门大炮。如果不能摧毁所有司机的大炮,则输出-1。

解析

首先,既然我们开挂,那么我们肯定是拿自己如果被打的话连锁爆炸少的去打对面多的,因为我们开炮打了别人,别人肯定是优先打我们露出来的这个炮比较划算,这样子换的话最后如果我们打的过的话我们剩下的就是最多的,这样子我们就先把我们自己的和对面的炮,连锁在一起的画成一个区域,毕竟如果我们打对面的甲炮会引爆乙炮,打乙炮同样是会引爆甲炮,所以我采用了并查集,将会连锁引爆的炮划在一起,这样子如果我们的区域大于等于对面我们就能赢(因为我们先手,最后一轮把对面的打掉之后对面就没有炮反击了),关于并查集->这个是我以前学习并查集的时候写的博客

代码

#include<bits/stdc++.h>
using namespace std;
const int N=101;
char a[N][N];
int dx[8]={0,0,1,-1,1,-1,1,-1};
int dy[8]={1,-1,0,0,1,-1,-1,1};
int fa[N*N],siz[N*N],m,sav[N*N],e,t;
inline int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
inline void merge(int x,int y){
    int a=find(x),b=find(y);
    if(a!=b){
        fa[a]=b,siz[b]+=siz[a];
    }
}
int main(void){
    scanf("%d",&m);
    for(int i=1;i<=8;++i){
        for(int j=1;j<=m;++j){
            scanf(" %c",&a[i][j]);fa[(i-1)*m+j]=(i-1)*m+j,siz[(i-1)*m+j]=1;
        }
    }
    for(int i=1;i<=8;++i){
        for(int j=1;j<=m;++j){
            if(a[i][j]=='*'){
                for(int k=0;k<8;++k){
                    int x=i+dx[k],y=j+dy[k];
                    if(((i<=4&&x&&x<=4)||(i>4&&x>4&&x<=8))&&y&&y<=m){
                        if(a[x][y]=='*'){
                            merge((x-1)*m+y,(i-1)*m+j);
                        }
                    }
                }
            }
        }
    }
    for(int i=1;i<=8;++i){
        for(int j=1;j<=m;++j){
            if(a[i][j]=='*'&&fa[(i-1)*m+j]==(i-1)*m+j){
                if(i<=4){
                    ++t;
                }else{
                    sav[++e]=siz[(i-1)*m+j];
                }
            }
        }
    }
    if(e<t){
        printf("-1\n");
        return 0;
    }
    sort(sav+1,sav+e+1);
    int ans=0;
    for(int i=t;i<=e;++i){
        ans+=sav[i];
    }
    printf("%d\n",ans);
    return 0;
}
每日一题 文章被收录于专栏

写每日一题呀

全部评论

相关推荐

尊嘟假嘟点击就送:加v细说,问题很大
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务