题目描述

给定一个n × m的矩形地图,每个各自上可能为空,可能有牌,牌上有一个数字。

对于两张同样数字的牌,如果我们可以在地图上用不超过三根水平或竖直,在地图界内,且不经过其他牌的线段将两张牌连起来,那么我们这一对牌是可以被消去的。

比如下图中,两张1可以被消去,但是2和3都不能被消去。 

现在给出一个n × m的连连看地图,其中有2k张牌,保证每张牌上的数字都在[1, k]范围内,且每个数字都只会出现两次,问目前有多少对牌是可以消去的。

输入输出格式

输入格式:

输入第一行三个正整数n, m, k,分别代表地图的长,宽以及牌的对数。

接下来k行每行四个正整数x1 , y1 , x2 , y2,表示数字为k的两张牌的位置。

输出格式:

输出仅一行一个整数,表示当前可以消去的牌的对数

输入输出样例

输入样例#1: 复制

3 3 3
1 3 2 2
1 1 3 3
1 2 2 1
输出样例#1: 复制

1

说明

30%的数据 n, m≤ 20,k<=min(3, ⌊ n*m/2 ⌋)

接下来30%的数据 n, m≤ 100,k<=min(100, ⌊ n*m/2 ⌋)

接下来30%的数据 n, m≤ 1000,k<=min(5000, ⌊ n*m/2 ⌋)

题解


考虑数据范围很小,我们可以做各种n方操作。

读入的同时把相应坐标标记

    flag[ i ] [ j ]=1;

套两个for循环,分别求横排上的前缀和 及竖排上的前缀和

    for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
ss[i][j]=ss[i-1][j]+tu[i][j],
hs[i][j]=hs[i][j-1]+tu[i][j];

对于每组牌:

我们把一张牌分别向上下左右暴力走,走到边界或障碍就停,经过的点就标记。(画十字)

|____________|
| O |
| | O |
| | |
| O——O————O|
| | |
| | |
| O | |
|______|_____|

然后把第二张牌也上下左右暴力走,同样经过则标记。如果有到被标记过的点,说明路线相交了,这对牌可消,flag=1

若未相交:

从1~n枚举横坐标j,如果这一段(< x1 , j >点到 < x2 , j >点)上的区间和为0
且< x1 , j >点和< x2 , j >点被标记过(画十字的时候经历过)的话(用前缀和O(1)查询)
则这一段没有障碍,可以连线,flag=1

从1~n枚举纵坐标i,如果< i , y1 >点到< i , y2 >上的区间和为0,则可连,flag=1

最后如果flag为1,则ans++

代码://考场代码

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
inline int read()//快读
{
char ch=getchar();
int x=;bool s=;
while(ch<''||ch>''){if(ch=='-')s=;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-;ch=getchar();}
return s?x:-x;
}
int lx[],ly[],rx[],ry[];
int ss[][];
int hs[][];
bool tu[][];
bool sf[][];
int main()
{
int n=read(),m=read(),k=read();
for(int i=;i<=k;++i)
{
lx[i]=read(),
ly[i]=read(),
rx[i]=read(),
ry[i]=read();
tu[lx[i]][ly[i]]=;
tu[rx[i]][ry[i]]=;//标记
}
for(int i=;i<=n+;++i)
tu[i][]=tu[i][m+]=;
for(int i=;i<=m+;++i)
tu[][i]=tu[n+][i]=;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
ss[i][j]=ss[i-][j]+tu[i][j],
hs[i][j]=hs[i][j-]+tu[i][j];//前缀和
int ans=;
for(int c=;c<=k;++c)
{
int flag=;
memset(sf,,sizeof(sf));
//以下一大堆为画十字
tu[lx[c]][ly[c]]=;
tu[rx[c]][ry[c]]=;//便于之后操作
int x=lx[c],y=ly[c];
int l,r,u,d;
while(!tu[x][y]){sf[x--][y]=;}
u=x+;
x=lx[c]+,y=ly[c];
while(!tu[x][y]){sf[x++][y]=;}
d=x-;
x=lx[c],y=ly[c]-;
while(!tu[x][y]){sf[x][y--]=;}
l=y+;
x=lx[c],y=ly[c]+;
while(!tu[x][y]){sf[x][y++]=;}
r=y-;
x=rx[c],y=ry[c];
while(!tu[x][y]){if(sf[x][y])flag++;sf[x--][y]=;}
u=max(u,x+);
x=rx[c]+,y=ry[c];
while(!tu[x][y]){if(sf[x][y])flag++;sf[x++][y]=;}
d=min(d,x-);
x=rx[c],y=ry[c]-;
while(!tu[x][y]){if(sf[x][y])flag++;sf[x][y--]=;}
l=max(l,y+);
x=rx[c],y=ry[c]+;
while(!tu[x][y]){if(sf[x][y])flag++;sf[x][y++]=;}
r=min(r,y-);
//画十字结束
if(!flag)
{
int zx=lx[c],zy=ly[c],yx=rx[c],yy=ry[c];
if(zx>yx)swap(zx,yx);
if(zy>yy)swap(zy,yy);
for(int i=u;i<=d;++i)//枚举横坐标
if(hs[i][yy]-hs[i][zy-]==)flag++;
for(int j=l;j<=r;++j)//枚举纵坐标
if(ss[yx][j]-ss[zx-][j]==)flag++;
}
if(flag)ans++;
tu[lx[c]][ly[c]]=;
tu[rx[c]][ry[c]]=;//复原
//cout<<flag<<endl;
}
cout<<ans;//强大怪!!!
return ;
}

//强大怪!!!(滑稽

「HNSDFZ暑期集训 测试1」「LuoguT36488」 连连看的更多相关文章

  1. 「HNSDFZ暑期集训 测试1」「LuoguT36485」 括号(贪心

    Description 给定一个由左括号'('和右括号')'组成的字符串s,其中第i个括号的权值为ai. 我们定义一个括号序列t为合法括号序列,当且仅当满足下列条件之一: 1.t为空串 2.t=(A) ...

  2. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 …… 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  3. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

  4. 「雅礼集训 2017 Day7」事情的相似度

    「雅礼集训 2017 Day7」事情的相似度 题目链接 我们先将字符串建后缀自动机.然后对于两个前缀\([1,i]\),\([1,j]\),他们的最长公共后缀长度就是他们在\(fail\)树上对应节点 ...

  5. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  6. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

  7. [LOJ 6031]「雅礼集训 2017 Day1」字符串

    [LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...

  8. [LOJ 6030]「雅礼集训 2017 Day1」矩阵

    [LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...

  9. [LOJ 6029]「雅礼集训 2017 Day1」市场

    [LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...

随机推荐

  1. 【深入Java虚拟机】之五:多态性实现机制——静态分派与动态分派

    方法解析 Class文件的编译过程中不包含传统编译中的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址.这个特性给Java带来了更强大的动态扩 ...

  2. error MIDL2311 解决方法

    error MIDL2311 : statements outside library block are illegal in mktyplib compatability mode : [] 在编 ...

  3. js -- 侧边悬浮栏特效

    github: https://github.com/mybee/float-scroll-page #menu{width: 120px;height: auto; position: fixed; ...

  4. Donser Online Judge 完成运行使命~

    复试成功完成~ 2018年网研机考难度不大,仍然有些遗憾,前两题水题后两个题纯暴力 排行榜 排名 用户 题数 罚时 A B C D retest2018_INT246 (INT246) (+) (+) ...

  5. gulp - sass 插件一直安装不好?

    1.没有sass,只存在与scss 任务 gulp.task('scss', function() { return gulp.src(app.srcPath + '/sass/*.scss') .p ...

  6. 《Deep Learning》全书已完稿_附全书电子版

    Deep Learning第一篇书籍最终问世了.站点链接: http://www.deeplearningbook.org/ Bengio大神的<Deep Learning>全书电子版在百 ...

  7. LZMA C# SDK 结合 UPK 打包压缩 多目录 Unity3d实例

    上篇  LZMA C# SDK 子线程压缩与解压缩 Unity3d实例  讲了怎样使用 LZMA C# SDK 来对文件进行压缩与解压,当中提到 对于多目录能够先打包成 UPK 然后再 LZMA 压缩 ...

  8. C++ 模板应用浅析

    把曾经写的C++模板的应用心得发表出来. 回忆起当时在学习C++模板时的无助和恐惧,如今还心有余悸.我分享出来我的心得,仅仅希望别人少走弯路,事实上它就这么几种使用方法,不须要害怕. 我总结了模板的四 ...

  9. Arcgis Engine(ae)接口详解(8):临时元素(element)

    //主地图的地图(map)对象 IMap map = null; IActiveView activeView = null; //IGraphicsContainer用于操作临时元素,可以通过map ...

  10. run as maven test报错解决办法

    eclipse中使用maven插件的时候,运行run as maven build的时候报错 -Dmaven.multiModuleProjectDirectory system propery is ...