Gym - 101550A(Artwork 倒序+并查集)
题目:

思路:
1、对输入数据离线,先把所有的黑线都画出来,统计一下剩余的白色连通块的个数,dfs过程将一个连通块放到一个集合中。
2、倒着往前消去黑线,如果当前的块A是白块就看他的四周有没有白块:有白块B,看A和B的祖先是不是一样,一样的话pass,否则合并连通块并且白色连通块的数目减一(当然第一个是跳过的)。四周全是黑块的话,白色连通块的数量加一。
3、用栈存储一下每一步的答案,最后输出就可以了。
PS:看错了q的数据范围,卡了三天,话说前两天答案状态是WA在test5,第三天就成了memor limit exceeded,然后就发现自己的错误了。菜是原罪啊!!
代码:
#include <bits/stdc++.h>
#define inf 1e9
#define FRE() freopen("in.txt","r",stdin)
using namespace std;
typedef long long ll;
const ll MOD = ;
const int maxn = 1e3+;
int mp[maxn][maxn],fa[maxn*maxn],vis[maxn][maxn];
int dir[][] = {{,},{-,},{,},{,-}};
struct label
{
int r1,c1;
int r2,c2;
} l[maxn*];
int r,c,q,num_white; int getId(int x,int y)
{
return x*c+y;
} void init()
{
num_white = ;
memset(mp,,sizeof(mp));
memset(vis,,sizeof(vis));
for(int i = ; i<maxn*maxn; i++)
{
fa[i] = i;
}
return;
} int Find(int x)
{
return fa[x]==x ? x : fa[x] = Find(fa[x]);
} void input()
{
int x1,x2,y1,y2;
for(int i = ; i<q; i++)
{
scanf("%d%d%d%d",&l[i].c1,&l[i].r1,&l[i].c2,&l[i].r2);
l[i].c1--,l[i].c2--,l[i].r1--,l[i].r2--;
if(l[i].r1==l[i].r2)
{
int x = l[i].r1;
for(int j = l[i].c1; j<=l[i].c2; j++)
mp[x][j]++;
}
else if(l[i].c1==l[i].c2)
{
int y = l[i].c2;
for(int j = l[i].r1; j<=l[i].r2; j++)
mp[j][y]++;
}
}
} bool inside(int x,int y)
{
if(x>= && x<r && y>= && y<c)
return true;
return false;
} void dfs(int x,int y,int iid)
{
int id = getId(x,y);
vis[x][y] = ;
fa[id] = iid;
for(int i = ; i<; i++)
{
int tx = x+dir[i][],ty = y+dir[i][];
if(inside(tx,ty) && !mp[tx][ty] && !vis[tx][ty])
{
dfs(tx,ty,iid);
}
}
return;
} bool _union(int x,int y)
{
int tx = Find(x),ty = Find(y);
if(tx!=ty)
{
fa[tx] = ty;
return true;
}
return false;
} void solve(int x,int y)
{
int f = ,isfirst = ;
for(int i = ; i<; i++)
{
int tx = x+dir[i][],ty = y+dir[i][];
if(inside(tx,ty))
{
if(!mp[tx][ty])
{
f = ;
if(_union(getId(x,y),getId(tx,ty)))
{
isfirst++;
if(isfirst == )
continue;
else
num_white--;
}
}
}
}
if(!f)
num_white++;
} void check()
{
for(int i = ; i<r; i++)
{
for(int j = ; j<c; j++)
{
printf("%d ",mp[i][j]);
}
printf("\n");
}
cout<<"GG"<<endl;
} void countWhite()
{
for(int i = ; i<r; i++)
{
for(int j = ; j<c; j++)
{
int id = getId(i,j);
if(!mp[i][j] && !vis[i][j])
{
dfs(i,j,id);
num_white++;
}
}
}
} int main()
{
//FRE();
scanf("%d%d%d",&c,&r,&q);
init();
input();
countWhite();
stack<int> ans;
for(int i = q-; i>=; i--)
{
ans.push(num_white);
int x1 = l[i].r1,x2=l[i].r2,y1=l[i].c1,y2=l[i].c2;
if(x1==x2)
{
for(int j=y1; j<=y2; j++)
{
mp[x1][j]--;
if(mp[x1][j]==)
{
solve(x1,j);
}
}
}
else if(y1==y2)
{
for(int j=x1; j<=x2; j++)
{
mp[j][y1]--;
if(mp[j][y1]==)
{
solve(j,y1);
}
}
}
//check();
}
while(!ans.empty())
{
printf("%d\n",ans.top());
ans.pop();
}
return ;
}
/*
4 6 5
2 2 2 6
1 3 4 3
2 5 3 5
4 6 4 6
1 6 4 6
*/
/*
1
3
3
4
3
*/
Gym - 101550A(Artwork 倒序+并查集)的更多相关文章
- Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C 倒序并查集
C. Destroying Array time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Gym - 101550A Artwork (并查集在线做法)
题目链接 题意:给你一个n*m的网格图,初始时格点全白,每次可以将一段连续的格点涂黑.求出每次操作之后白色连通块的数量. 看了看网上的题解,基本全是离线的做法.其实这道题是有在线的做法的,利用了对偶图 ...
- Gym 100814C Connecting Graph 并查集+LCA
Description standard input/output Statements Alex is known to be very clever, but Walter does not be ...
- Gym - 101243F Vitamins(思维+并查集)
题意 有三种药丸,白色W>红色R>蓝色B,给你m个约束条件,问你n个药丸的颜色,不能确定颜色输出‘?’ 题解 如果1<2<3,只要找到2就能确定1和3的颜色 如果2=4,只要确 ...
- 【BZOJ2054】疯狂的馒头(并查集)
/* 经典思路, 倒序并查集处理即可 */ #include<cstdio> #include<algorithm> #include<cstring> #incl ...
- 并查集【洛谷P1197】 [JSOI2008]星球大战
P1197 [JSOI2008]星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系 ...
- Artwork Gym - 101550A 离线并查集
题目:题目链接 思路:每个空白区域当作一个并查集,因为正着使用并查集分割的话dfs会爆栈,判断过于复杂也会导致超时,我们采用离线反向操作,先全部涂好,然后把黑格子逐步涂白,我们把每个空白区域当作一个并 ...
- Codeforces Gym 100463E Spies 并查集
Spies Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Desc ...
- Gym - 100625G Getting Through 计算几何+并查集
http://codeforces.com/gym/100625/attachments/download/3213/2013-benelux-algorithm-programming-contes ...
随机推荐
- 在vs2017中创建Node.js项目
https://github.com/Microsoft/nodejstools/wiki/Projects 1. 安装vs2017的时候,需要勾选Node.js 2.新建项目的时候,选择其他语言,然 ...
- JFreeChart简单用法
需要用到的包 jfreechart-0.9.20.jar,jcommon-0.9.5.jar 创建一般步骤: 1.生成org.jfree.data.DefaultCategoryDataset对象,方 ...
- 【Codevs 4672】辛苦的老园丁
http://codevs.cn/problem/4672/ 那个一看这不是(最大独立集)的最大权值和,类似 反图→ 最大团 NP问题 搜索解决 改一下模板即可 参考最大独立集 Maximum C ...
- Mac os x下配置 Android ndk 开发环境
1.阅读下面之前,请确保你android sdk的开发环境已经搭建好,ADT也最好是目前最新的. 2.到http://developer.android.com/tools/sdk/ndk/index ...
- Opencv+Zbar二维码识别(一维码校正)
一维码由一组规则排列的黑色线条.白色线条以及对应的字符组成.对倾斜的(没有严重形变)一维码的角度校正,可以根据其黑白相间.排列规则的特点,计算傅里叶频谱,通过傅里叶频谱中直线的倾斜角度计算空间域图像一 ...
- android 手机上运行图像算法
在pc上调试好的图像处理算法想要在android手机上跑一下看看速度需要一下几个步骤 1.建立一个android application,通过ndk调用你写好的图像算法的c/c++ code 2. 然 ...
- 转贴:CSS伪类与CSS伪元素的区别及由来具体说明
关于两者的区别,其实是很古老的问题.但是时至今日,由于各种网络误传以及一些不负责任的书籍误笔,仍然有相当多的人将伪类与伪元素混为一谈,甚至不乏很多CSS老手.早些年刚入行的时候,我自己也被深深误导,因 ...
- vue中父组件传数据给子组件
父组件: <template> <parent> <child :list="list"></child> //在这里绑定list对 ...
- P3258[JLOI2014]松鼠的新家(LCA 树上差分)
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- Swift5.1 语言指南(二十九)高级运算符
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...