【JZOJ 3809】设备塔

Description

为了封印辉之环,古代塞姆利亚大陆的人民在异空间中建造了一座设备塔。
简单的说,这座设备塔是一个漂浮在异空间中的圆柱体,圆柱体两头的圆是计算核心,而侧面则是
传输信息所用的数据通道,划分成N *m 个区块。
然而,随着工作的继续进行,他们希望把侧面的一部分区块也改造成其他模块。然而,任何时候都
必须保证存在一条数据通道,能从圆柱体的一端通向另一端。
由于无法使用辉之环掌控下的计算系统,他们寻求你的帮助来解决这个问题。他们将逐个输入想要
改造的区域,而你则执行所有可行的改造并忽略可能导致数据中断的改造。

Solution

先把原来的倍长一倍,
有一个已经放了的点,如果它附近(8个方向)还有点,则这两个点联通,
每次加上一个点,就看看加上它在图中的原位置和倍长后的位置,这两个点是否联通,是则不能放,

复杂度: O(nm)

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define min(q,w) ((q)<(w)?(q):(w))
#define OK(q) ((q)>0&&(q)<=n)
#define H(q,w) ((q)*m-m+(w)) 
using namespace std;
const int N=5005;
int read(int &n)
{
    char ch=' ';int q=0,w=1;
    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
    if(ch=='-')w=-1,ch=getchar();
    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int n,m,Ti,ans,m1;
int g[N*2*N];
int fx[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
int y1[8],y[8];
int z[N][N*2];
int gf(int q){return g[q]==q?q:g[q]=gf(g[q]);}
bool OK1()
{
    fo(i,0,7)fo(j,0,7)if(y[i]==y1[j]&&y[i])return 0;
    return 1;
}
int main()
{
    int q,w,e,q1,w1;
    read(n),read(m),read(m1);
    e=m;m*=2;
    fo(i,1,n)fo(j,1,m)g[H(i,j)]=H(i,j);
    if(m==2){printf("1\n");return 0;}
    fo(I,1,m1)
    {
        read(q),read(w);
        int x=gf(g[H(q,w)]);
        fo(k,0,7)if(OK(q+fx[k][0]))
        {
            q1=q+fx[k][0];
            if(z[q1][w1=1+(w-1+fx[k][1]+m)%m])y[k]=gf(H(q1,w1));
            else y[k]=0;
        }else y[k]=0;
        w+=e;
        int x1=gf(g[H(q,w)]);
        fo(k,0,7)if(OK(q+fx[k][0]))
        {
            q1=q+fx[k][0];
            if(z[q1][w1=1+(w-1+fx[k][1]+m)%m])y1[k]=gf(H(q1,w1));
            else y1[k]=0;
        }else y1[k]=0;
        if(OK1())
        {
            fo(k,0,7)g[y[k]]=x;
            fo(k,0,7)g[y1[k]]=x1;
            g[0]=0;
            ans++;
            z[q][w]=1;z[q][w-e]=1;
        }
    }
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值