【模拟】ZJOI2014&BZOJ3519消棋子

博客介绍了ZJOI2014及BZOJ3519消棋子问题的解决方案。关键在于理解图的方向,并利用set存储每行每列的点信息。对于第一部分,通过lower_bound找最接近点并检查有效性。第二部分涉及递归操作,删除点后更新可删除点,需注意避免错误的删除顺序导致错误结果。
摘要由CSDN通过智能技术生成

传送门
注:
图的方向要注意!如果你把方向看反了,样例仍然可以过(然而几乎所有测试数据都过不了)。
样例图例如下:
这里写图片描述

题目中给出,每种颜色只有2个,而且最多有100000种颜色。
那么很容易想到暴力算法。
用set分每行每列储存所有的点:
如一点坐标为(x,y)
那么就在y列插入x,同时在x行插入y
这样就可以通过迭代器,快速找到某个点每行每列相邻的的点。

对于1问,主要通过set的lower_bound来实现找最接近的点。
再写一个check检查是否为有效操作,如果是就删除这两个点。

对于2问,可以先把所有点扫一遍,找到可以删除的点,将其删除。
删除之后,就可能新增其他的可删除的点,简单分析可知,能够新增的点,与它相对应的点的连线一定经过删除的这个点(可以结合图像看一下)。
这里写图片描述
那么,在删除每个点时,向周围四个方向分别找到最近的点,再看这四个点能否可以删除。显然这是一个递归操作。

不过。。真正的难点是如何码代码。。
有一个实现细节:当你删除点之后,向周围四个方向找点,这时用check必须返回可以删除的点的颜色信息,否则会出现如下情况:
这里写图片描述
如果你只返回可不可行,那么就会把check1,check2删除,然而其实能删除的是new1和new2。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define SF scanf
#define PF printf 
#define MAXN 100010
using namespace std;
int n,m,C,R,cnt,xa[3],ya[3],tot,cnta;
int a1[MAXN],a2[MAXN],a3[MAXN],a4[MAXN];
vector<pair<int,int> >del,l1,r1;
vector<int> dec;
set<int> l[MAXN],r[MAXN];
map<pair<int,int>,int> col;
int check(int x,int y,char c1,char c2){
    cnta=0;
    if(col[make_pair(x,y)]!=0)
        return 0;
    if(c1=='U&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值