D e s c r i p t i o n Description Description
为了封印辉之环,古代塞姆利亚大陆的人民在异空间中建造了一座设备塔。
简单的说,这座设备塔是一个漂浮在异空间中的圆柱体,圆柱体两头的圆是计算核心,而侧面则是
传输信息所用的数据通道,划分成N *m 个区块。
然而,随着工作的继续进行,他们希望把侧面的一部分区块也改造成其他模块。然而,任何时候都
必须保证存在一条数据通道,能从圆柱体的一端通向另一端。
由于无法使用辉之环掌控下的计算系统,他们寻求你的帮助来解决这个问题。他们将逐个输入想要
改造的区域,而你则执行所有可行的改造并忽略可能导致数据中断的改造。
I n p u t Input Input
第一行,包含两个整数N;M;K,表示侧面的长和宽,以及操作数。
接下来K 行,每行包含三个整数xi; yi,表示操作的区块的坐标。(0<=y=<M)
数据保证不会对已经操作成功的区块进行操作。
O u t p u t Output Output
输出一行,表示有多少个操作可以被执行。
S a m p l e I n p u t SampleInput SampleInput
3 4 9
2 2
3 2
2 3
3 4
3 1
1 3
2 1
1 1
1 4
S a m p l e O u t p u t SampleOutput SampleOutput
6
思路
判断从上到下是否有路径
其实就是判断放的方块是否能够连成一块
就等于将
n
∗
m
n*m
n∗m的图复制一遍
每一次放就等于放两个方块
然后让方块时判断两个方块附近的方块是否连通
(这里用到并查集)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int dx[9] = {0, 1, 1, 1, 0, -1, -1, -1, 0};
const int dy[9] = {0, 1, 0, -1, -1, -1, 0, 1 ,1};
int Fa[600015], M[3005][6015];
int Ans, n, m, t, x, y, sx, sy;
int Read()//快读,然后并没有什么卵用
{
int l = 0, r = 1; char k = getchar();
while(!(k >= '0' && k <= '9') && k != '-')break;
if(k < '0' || k > '9')r = -1, k = getchar();
while(k >= '0' && k <= '9')l = l * 10 + k - '0', k = getchar();
return l * r;
}
bool Check(int x, int &y)//判断是否超界,并且将越界的y弄到另一边(因为他是圆柱)
{
if(x < 1 || x > n)return 0;
if(y < 1)y = 2 * m;
if(y > 2 * m)y = 1;
if(!M[x][y])return 0;
return 1;
}
int find(int k)//并查集
{
if(Fa[k] == k)return k;
return Fa[k] = find(Fa[k]);
}
bool init(int xx, int xy)
{
int yx = xx, yy = xy + m;//复制出来的方块位置
for(int i = 1; i <= 8; ++i)//第一个四周的方块
{
int lx = xx + dx[i];
int ly = xy + dy[i];
if(!Check(lx, ly))continue;
for(int j = 1; j <= 8; ++j)//第一个四周的方块(因为同一个方向可能并不连通,所以要两个for)
{
int rx = yx + dx[j];
int ry = yy + dy[j];
if(!Check(rx, ry))continue;
if(find(M[lx][ly]) == find(M[rx][ry])
&& M[lx][ly] && M[rx][ry])return 0;//判断是否连通
}
}
return 1;
}
void bol(int x, int y)
{
int la = find(x);
int lb = find(y);
if(la < lb)Fa[lb] = la;
else if(la > lb)Fa[la] = lb;//归为同一个祖先
return;
}
void build(int x,int y)
{
M[x][y] = ++Ans;
Fa[Ans] = Ans;
for(int i = 1; i <= 8; i++)//找祖先
{
int l = x + dx[i];
int r = y + dy[i];
if(!Check(l, r))continue;
bol(M[x][y],M[l][r]);
}
return;
}
int main()
{
scanf("%d%d%d", &n, &m, &t);
for(int l = 1; l <= t; l++)
{
scanf("%d%d", &x, &y);
if(init(x, y))
{
build(x, y);
build(x, y + m);
}
}
printf("%d", Ans / 2);
return 0;
}