Description
为了封印辉之环,古代塞姆利亚大陆的人民在异空间中建造了一座设备塔。
简单的说,这座设备塔是一个漂浮在异空间中的圆柱体,圆柱体两头的圆是计算核心,而侧面则是传输信息所用的数据通道,划分成N *m 个区块。
然而,随着工作的继续进行,他们希望把侧面的一部分区块也改造成其他模块。然而,任何时候都必须保证存在一条数据通道,能从圆柱体的一端通向另一端。
由于无法使用辉之环掌控下的计算系统,他们寻求你的帮助来解决这个问题。他们将逐个输入想要改造的区域,而你则执行所有可行的改造并忽略可能导致数据中断的改造。
Solution
因为是环,所以复制一份。
然后每个点向四周非空的方块连边,那么判断不合法就是判断该点和复制后的点是否联通。
Code
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 3010
using namespace std;
int fx[8][2]={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}};
int n,m;
int f[N*N*2];
bool bz[N][N*2];
int g(int x,int y){
return (x-1)*m*2+y;
}
int find(int x){
return !f[x]?x:f[x]=find(f[x]);
}
int main()
{
int t;
scanf("%d %d %d",&n,&m,&t);
int ans=0;
while(t--)
{
int x,y;
scanf("%d %d",&x,&y);
if(!y) y=m;
bool tf=false;
fo(i,0,7)
{
int x1=x+fx[i][0],y1=(y+fx[i][1])%(m*2);
if(!y1) y1=m*2;
if(x1<1 || x1>n) continue;
if(!bz[x1][y1]) continue;
fo(j,0,7)
{
int x2=x+fx[j][0],y2=(y+m+fx[j][1])%(m*2);
if(!y2) y2=m*2;
if(x2<1 || x2>n) continue;
if(!bz[x2][y2]) continue;
int t1=find(g(x1,y1)),t2=find(g(x2,y2));
if(t1==t2)
{
tf=true;
break;
}
}
if(tf) break;
}
if(!tf)
{
ans++;
fo(i,0,7)
{
int t;
int x1=x+fx[i][0],y1=(y+fx[i][1])%(m*2);
if(!y1) y1=m*2;
if(x1<1 || x1>n) continue;
if(!bz[x1][y1]) continue;
int t1=find(g(x1,y1));
t=find(g(x,y));
if(t1!=t) f[t1]=t;
}
fo(i,0,7)
{
int t;
int x2=x+fx[i][0],y2=(y+m+fx[i][1])%(m*2);
if(!y2) y2=m*2;
if(x2<1 || x2>n) continue;
if(!bz[x2][y2]) continue;
int t2=find(g(x2,y2));
t=find(g(x,y+m));
if(t2!=t) f[t2]=t;
}
bz[x][y]=bz[x][y+m]=1;
}
}
printf("%d",ans);
}