题目:

思路:

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 倒序+并查集)的更多相关文章

  1. 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 ...

  2. Gym - 101550A Artwork (并查集在线做法)

    题目链接 题意:给你一个n*m的网格图,初始时格点全白,每次可以将一段连续的格点涂黑.求出每次操作之后白色连通块的数量. 看了看网上的题解,基本全是离线的做法.其实这道题是有在线的做法的,利用了对偶图 ...

  3. Gym 100814C Connecting Graph 并查集+LCA

    Description standard input/output Statements Alex is known to be very clever, but Walter does not be ...

  4. Gym - 101243F Vitamins(思维+并查集)

    题意 有三种药丸,白色W>红色R>蓝色B,给你m个约束条件,问你n个药丸的颜色,不能确定颜色输出‘?’ 题解 如果1<2<3,只要找到2就能确定1和3的颜色 如果2=4,只要确 ...

  5. 【BZOJ2054】疯狂的馒头(并查集)

    /* 经典思路, 倒序并查集处理即可 */ #include<cstdio> #include<algorithm> #include<cstring> #incl ...

  6. 并查集【洛谷P1197】 [JSOI2008]星球大战

    P1197 [JSOI2008]星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系 ...

  7. Artwork Gym - 101550A 离线并查集

    题目:题目链接 思路:每个空白区域当作一个并查集,因为正着使用并查集分割的话dfs会爆栈,判断过于复杂也会导致超时,我们采用离线反向操作,先全部涂好,然后把黑格子逐步涂白,我们把每个空白区域当作一个并 ...

  8. Codeforces Gym 100463E Spies 并查集

    Spies Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Desc ...

  9. Gym - 100625G Getting Through 计算几何+并查集

    http://codeforces.com/gym/100625/attachments/download/3213/2013-benelux-algorithm-programming-contes ...

随机推荐

  1. Bootstrap 模态窗口源码分析

    前言: bootstrap的 js插件的源码写的非常好,也算是编写jquery插件的模范写法,本来还想大篇详细的分析一下呢,唉,没时间啊,很早之前看过的源码了,现在贴在了博客上, 300来行的代码,其 ...

  2. Hibernate - Query简易

    package cn.demo; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; im ...

  3. 【T^T】【周赛】第一周周赛——欢迎16级的新同学

    借光光,YZC的福气(今天拿到Rank1),本来还可以更好的,前面吃M去了,ABC都很晚切,而且异常兴奋,结果WA了好多发,但还是由于水题看题不清,分析不清导致的 A Home W的数学 Descri ...

  4. [odb-users] query results not being cached?

    Burton, Craig crburton at tnsi.comWed Jun 6 13:58:03 EDT 2012 Previous message: [odb-users] query re ...

  5. 使用vue-cli启动项目出错

    Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架. Vue 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 API 实现响应的数据 ...

  6. TI BLE:SCAN

    主机会运行SCAN来搜寻广播中的设备 运行函数: GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_AC ...

  7. java自学-方法

    上节介绍了流程控制语句,一个复杂的业务逻辑会由很多java代码组成,包含许多功能.比如说购物业务,就包含选商品.下单.支付等功能,如果这些功能的代码写到一起,就会显得很臃肿,可读性非常不好.java提 ...

  8. spring 简单实现BeanFactory(转)

    原文地址: http://blog.csdn.net/mlc1218559742/article/details/52776160 有没有发现上面的代码与利用反射实现工厂模式的代码很相似.对,你没有看 ...

  9. 51nod1459 迷宫游戏

    1459 迷宫游戏 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 你来到一个迷宫前.该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你 ...

  10. A8ERP权限管理系统