题目描述

给定一个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. 2017 ACM/ICPC Asia Regional Urumuqi Online 记录

    比赛题目链接  Urumuqi

  2. [bzoj1110][POI2007]砝码Odw_贪心

    bzoj-1110 POI-2007 砝码Odw 参考博客:http://hzwer.com/4761.html 题目大意:在byteotian公司搬家的时候,他们发现他们的大量的精密砝码的搬运是一件 ...

  3. NIO与传统IO的区别(形象比喻)[转]

    传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大.使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数 ...

  4. 【Android开发—智能家居系列】(四):UDP通信发送指令

    思路回顾 [1]手机连接WIFI模块 [2]UDP通信对WIFI模块发送指令,以和WIFI模块保持连接状态 [3]UDP通信对WIFI模块发送指令,让其搜索可用的无线网,返回WIFI列表 [4]发送指 ...

  5. 聊聊WiFi Hacks:为何你的Karma攻击不好使了

    0.前言 三年前我发表了一篇文章<黑客有办法让你自动连上陌生WiFi>,介绍Karma攻击可以让你的无线设备自动连上黑客的WiFi.当时引起了还算比较热烈的讨论,关于WiFi安全,关于Ka ...

  6. BUPT复试专题—日期(2013)

    题目描述 请你计算出第年月日是第X年的第几天.其中,1月1日是第一天,1月2日是第二天,以此类推. 计算时请注意闰年的影响.对于非整百年,年数能整除4是闰年,否则不是闰年:对于整百年,年数能整除400 ...

  7. [转]文件IO详解(二)---文件描述符(fd)和inode号的关系

    原文:https://www.cnblogs.com/frank-yxs/p/5925563.html 文件IO详解(二)---文件描述符(fd)和inode号的关系 ---------------- ...

  8. 【Android小项目】找不同,改编自&quot;寻找房祖名&quot;的一款开源小应用。

    近期在微信朋友圈"寻找房祖名"和"万里寻刀"这类小游戏比較火.我试着写了一个android版本号的,里面全是一系列的形近字,实现原理非常easy:用一个Grid ...

  9. SolidEdge 如何绘制辅助视图

    如果你要创建辅助视图,则点击辅助视图按钮,然后鼠标滑过要正视的面上,出现灰色的时候向上拉即可.   你可以右击箭头,点击性质,改变箭头的符号等样式.  

  10. FLEX接收外部参数 .

    FLEX参数传递与FLASH有点不同 login..swf?name=aa&password=bb Flex上是这样接收参数的 myname=mx.core.Application.appli ...