一、题意

对于一个矩阵,若干道命令,每道命令将会把某一段格子涂黑,请问每次涂黑之后矩阵中未被涂黑的块的数量?

二、思路

保存每道命令,并且忠实的执行他,到最后一步开始搜索联通块的数量,并将其保存。

之后对于每道命令做撤回操作。每次撤回之后重新扫描命令覆盖区域中已经是空白块的区域。并且将它们用并查集的方式统一起来。

最后倒序输出保存的答案。

三、代码实现

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<set>
#include<map>
#include<string>
#include<queue> using namespace std;
#define ll long long
#define veci vector<int>
#define pp pair<ll,ll>
#define vecp vector<pp> const ll MAXN=; class point
{
public :
int x;int y;
point(){}
point(int a,int b):x(a),y(b){}
bool const operator == (point const &p1)
{
return x==p1.x&&y==p1.y;
}
}; class order
{
public :
point from,to;
order(){}
order(int a,int b,int c,int d)
{
from = point(a,b);
to = point(c,d);
}
};
ll n,m,k,num;
vector<order>ord;
veci ans;
point sett[MAXN][MAXN];
int mapp[MAXN][MAXN];
int addx[]={,,,-};
int addy[]={,-,,}; void draw(order o1)
{
for(int i=o1.from.x;i<=o1.to.x;++i)
{
for(int j=o1.from.y;j<=o1.to.y;++j)
{
if(mapp[i][j]==-)mapp[i][j]=;
mapp[i][j]++;
}
}
}
void erase(order o1)
{
for(int i=o1.from.x;i<=o1.to.x;++i)
{
for(int j=o1.from.y;j<=o1.to.y;++j)
{
mapp[i][j]--;
}
} } const point ZERO(,); void dfs(int x,int y,point tar)
{
if(x<||x>n||y<||y>m||mapp[x][y]!=-||sett[x][y]==tar)return ;
sett[x][y]=tar;
mapp[x][y]=;
for(int i=;i<;++i)
{
dfs(x+addx[i],y+addy[i],tar);
}
} point find_set(int x,int y)
{
if(sett[x][y].x==x&&sett[x][y].y==y)return sett[x][y];
else return sett[x][y]=find_set(sett[x][y].x,sett[x][y].y);
} void show(point p1)
{
int x=p1.x;
int y=p1.y;
cout<<"x: "<<x<<" y: "<<y<<endl;
} void deal(order o1)
{
for(int i=o1.from.x;i<=o1.to.x;++i)
for(int j=o1.from.y;j<=o1.to.y;++j)
{
if(mapp[i][j]==)
{
int isDealed=;
for(int k=;k<;++k)
{
int x=i+addx[k];
int y=j+addy[k];
if(x<||y<||x>n||y>m)continue;
if(mapp[x][y]==)
{
if(sett[x][y]==ZERO)continue;
if(!isDealed)
{
sett[i][j]=sett[x][y]=find_set(x,y); }else
{ sett[x][y]=find_set(x,y);
sett[i][j]=find_set(i,j);
if(sett[i][j]==sett[x][y])continue;
int xx=sett[x][y].x;
int yy=sett[x][y].y;
sett[xx][yy]=sett[i][j];
num--;
}
isDealed++;
}
}if(!isDealed)
{
sett[i][j]=point(i,j);
num++;
} }
} } void init()
{
num=;
ord.clear();
ans.clear();
memset(mapp,-,sizeof(mapp));
memset(sett,,sizeof(sett));
for(int i=;i<k;++i)
{
int a,b,c,d;
cin>>a>>b>>c>>d;
order o1(a,b,c,d);
draw(o1);
ord.push_back(o1);
}
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
{
if(mapp[i][j]==-)
{
point tar(i,j);
dfs(i,j,tar);
num++;
}
}
ans.push_back(num); int len=ord.size();
for(int i=len-;i;--i)
{
order now=ord[i];
erase(now);
deal(now);
ans.push_back(num);
}
len = ans.size();
for(int i=len-;i>=;--i)
cout<<ans[i]<<endl; } int main()
{
// cin.sync_with_stdio(false); while(cin>>n>>m>>k)init(); return ;
}

Artwork 18年中南多校第一场A的更多相关文章

  1. Card Hand Sorting 18中南多校第一场C题

    一.题意 随机给你一堆牌(标准扑克牌),之后让你按照: 第一优先规则:所有相同花色的在一起 第二优先规则:所有相同花色的必须按照升序或者降序排列 问,你最少要拿出多少张牌插入到其他的地方以维持这个状况 ...

  2. Highest Tower 18中南多校第一场H题

    一.题意 给出N个方块,要求给出一个方案,使得1. 所有方块都被使用到(题目数据保证这点) 2.所有方块垒成一个塔,且上面的方块宽度小于下面的方块 3.每个方块只能用一次,可以横着或者竖着. n范围5 ...

  3. 2019牛客多校第一场 I Points Division(动态规划+线段树)

    2019牛客多校第一场 I Points Division(动态规划+线段树) 传送门:https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点有 ...

  4. 牛客多校第一场 B Inergratiion

    牛客多校第一场 B Inergratiion 传送门:https://ac.nowcoder.com/acm/contest/881/B 题意: 给你一个 [求值为多少 题解: 根据线代的知识 我们可 ...

  5. HDU6581 Vacation (HDU2019多校第一场1004)

    HDU6581 Vacation (HDU2019多校第一场1004) 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6581 题意: 给你n+1辆汽车, ...

  6. 2019年牛客多校第一场B题Integration 数学

    2019年牛客多校第一场B题 Integration 题意 给出一个公式,求值 思路 明显的化简公式题,公式是分母连乘形式,这个时候要想到拆分,那如何拆分母呢,自然是裂项,此时有很多项裂项,我们不妨从 ...

  7. 2019HDU多校第一场1001 BLANK (DP)(HDU6578)

    2019HDU多校第一场1001 BLANK (DP) 题意:构造一个长度为n(n<=10)的序列,其中的值域为{0,1,2,3}存在m个限制条件,表示为 l r x意义为[L,R]区间里最多能 ...

  8. 2019年湖南多校第一场||2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

    第一场多校就打的这么惨,只能说自己太菜了,还需继续努力啊- 题目链接: GYM链接:https://codeforces.com/gym/101933 CSU链接:http://acm.csu.edu ...

  9. 【2019多校第一场补题 / HDU6578】2019多校第一场A题1001Blank——dp

    HDU6578链接 题意 有一串字符串,仅由 {0,1,2,3}\{0, 1, 2, 3\}{0,1,2,3} 组成,长度为 nnn,同时满足 mmm 个条件.每个条件由三个整数组成:l.r.xl.r ...

随机推荐

  1. Mysql 如何设置字段自动获取当前时间,附带添加字段和修改字段的例子

    --添加CreateTime 设置默认时间 CURRENT_TIMESTAMP  ALTER TABLE `table_name`ADD COLUMN  `CreateTime` datetime N ...

  2. mysql服务器查询慢原因分析方法

    mysql数据库在查询的时候会出现查询结果很慢,超过1秒,项目中需要找出执行慢的sql进行优化,应该怎么找呢,mysql数据库提供了一个很好的方法,如下: mysql5.0以上的版本可以支持将执行比较 ...

  3. 用简单的方法学习ES6

    ES6 简要概览 这里是ES6 简要概览.本文大量参考了ES6特性代码仓库,请允许我感谢其作者@Luke Hoban的卓越贡献,也感谢@Axel Rauschmayer所作的[优秀书籍]//explo ...

  4. git版本分支和分支、分支和主分支切换

    问题描述: 公司里项目管理使用的是gitLab(收费的), 如果开发人员提交代码,  需要首先创建一个分支, 然后把代码提交到你创建的分支上去(不允许把代码直接提交到主分支上). 在代码提交到已经创建 ...

  5. 微信jssdk实现分享到微信

    本来用的是这个插件http://overtrue.me/share.js/和百度分享 相同之处:在微信分享的时候,分享的链接都不能获取到缩略图... 不同之处:百度分享在微信低版本是可以看到缩略图的( ...

  6. 访问mongo数据库报错

    It looks like you are trying to access MongoDB over HTTP on the native driver port. 出错原因: 1.没有安装mong ...

  7. IOS 绘制条纹背景

    @interface NJViewController () @property (weak, nonatomic) IBOutlet UITextView *contentView; - (IBAc ...

  8. Linux命令的常用

    使用chown命令更改文件拥有者 在 shell 中,可以使用chown命令来改变文件所有者.chown命令是change owner(改变拥有者)的缩写.需要要注意的是,用户必须是已经存在系统中的, ...

  9. Oracle 事务 锁

    一. 事务 是一系列的数据库操作,是数据库应用的基本逻辑单位以及并发控制的基本单位.所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位. 要将有组语句作为事务考 ...

  10. 2018.10.30 NOIp模拟赛 T1 改造二叉树

    [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他又和他人讨论 ...