传送门
注:
图的方向要注意!如果你把方向看反了,样例仍然可以过(然而几乎所有测试数据都过不了)。
样例图例如下:
题目中给出,每种颜色只有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&#