爲了封印輝之環,古代塞姆利亞大陸的人民在異空間中建造了一座設備塔。
簡單的說,這座設備塔是一個漂浮在異空間中的圓柱體,圓柱體兩頭的圓是計算核心,而側面則是
傳輸信息所用的數據通道,劃分成N *m 個區塊。
然而,隨着工作的繼續進行,他們希望把側面的一部分區塊也改造成其他模塊。然而,任何時候都
必須保證存在一條數據通道,能從圓柱體的一端通向另一端。
由於無法使用輝之環掌控下的計算系統,他們尋求你的幫助來解決這個問題。他們將逐個輸入想要
改造的區域,而你則執行所有可行的改造並忽略可能導致數據中斷的改造。
第一行,包含兩個整數N;M;K,表示側面的長和寬,以及操作數。
接下來K 行,每行包含三個整數xi; yi,表示操作的區塊的座標。(0<=y=<M)
數據保證不會對已經操作成功的區塊進行操作.
輸出一行,表示有多少個操作可以被執行。
3 4 9
2 2
3 2
2 3
3 4
3 1
1 3
2 1
1 1
1 4
6
• 對於分值爲30 的子任務1,保證N;M <=100;K<= 5000
• 對於分值爲30 的子任務2,保證N;M <=3000;K <= 5000
• 對於分值爲40 的子任務3,保證N;M <=3000;K <= 300000。
黃色點表示可加的點,紅色點表示不可加的點
因爲是圓柱體,把原圖倍長一倍,每次加一個點,就在它這個圖的複製圖的對應點也標記上,判斷這兩個點是否聯通,聯通則不可加,否則就可以加
判斷是否聯通可以用並查集
但是!
∵ 如果你當前在 ,然後往左跳, 變爲 ,而 其實等於
∴ 需要這一類操作:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n, m, x, y, tot, t, ans;
int a[3005][6005], fa[2000005];
int dx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int dy[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int find(int x)
{
if (fa[x] == x) return x;
else return fa[x] = find(fa[x]);
}//尋找祖先
bool check(int x, int y)
{
int x2 = x, y2 = y + m;
for (int i = 0; i < 8; ++i)
{
int xa = x + dx[i], ya = y + dy[i];
if (ya < 1) ya = 2 * m;
if (ya > 2 * m) ya = 1;
if (xa < 1 || xa > n || !a[xa][ya]) continue;
for (int j = 0; j < 8; ++j)
{
int xb = x2 + dx[j], yb = y2 + dy[j];
if (yb > 2 * m) yb = 1;
if (yb < 1) yb = 2 * m;
if (xb < 1 || xb > n || !a[xb][yb]) continue;
if (a[xa][ya] && a[xb][yb] && find(a[xa][ya]) == find(a[xb][yb])) //判斷是否聯通
return 0;
}
}
return 1;
}
void unicom(int ax, int bx)
{
int Fa = find(ax), Fb = find(bx);
if (Fa == Fb) return;
if (Fa > Fb) fa[Fa] = Fb;
else fa[Fb] = Fa;
}//聯通祖先
void findfa(int tx, int ty)
{
a[tx][ty] = ++tot;
fa[tot] = tot;
for (int i = 0; i < 8; ++i)
{
int txa = tx + dx[i], tya = ty + dy[i];
if (tya < 1) tya = 2 * m;
if (tya > 2 * m) tya = 1;
if (txa < 1 || txa > n || !a[txa][tya]) continue;
unicom(tot, a[txa][tya]);
}
}
int main()
{
scanf("%d%d%d", &n, &m, &t);
for (int i = 1; i <= t; ++i)
{
scanf("%d%d", &x, &y);
if (check(x, y)) {//是否聯通
ans++;
findfa(x, y); findfa(x, y + m);//刷新它鄰點的祖先(並且幫當前點找到祖先)
}
}
printf("%d", ans);
}