「HNSDFZ暑期集训 测试1」「LuoguT36488」 连连看
题目描述
给定一个n × m的矩形地图,每个各自上可能为空,可能有牌,牌上有一个数字。
对于两张同样数字的牌,如果我们可以在地图上用不超过三根水平或竖直,在地图界内,且不经过其他牌的线段将两张牌连起来,那么我们这一对牌是可以被消去的。
比如下图中,两张1可以被消去,但是2和3都不能被消去。
现在给出一个n × m的连连看地图,其中有2k张牌,保证每张牌上的数字都在[1, k]范围内,且每个数字都只会出现两次,问目前有多少对牌是可以消去的。
输入输出格式
输入格式:
输入第一行三个正整数n, m, k,分别代表地图的长,宽以及牌的对数。
接下来k行每行四个正整数x1 , y1 , x2 , y2,表示数字为k的两张牌的位置。
输出格式:
输出仅一行一个整数,表示当前可以消去的牌的对数
输入输出样例
说明
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」 连连看的更多相关文章
- 「HNSDFZ暑期集训 测试1」「LuoguT36485」 括号(贪心
Description 给定一个由左括号'('和右括号')'组成的字符串s,其中第i个括号的权值为ai. 我们定义一个括号序列t为合法括号序列,当且仅当满足下列条件之一: 1.t为空串 2.t=(A) ...
- loj #6046. 「雅礼集训 2017 Day8」爷
#6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 …… 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...
- LOJ_6045_「雅礼集训 2017 Day8」价 _最小割
LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...
- 「雅礼集训 2017 Day7」事情的相似度
「雅礼集训 2017 Day7」事情的相似度 题目链接 我们先将字符串建后缀自动机.然后对于两个前缀\([1,i]\),\([1,j]\),他们的最长公共后缀长度就是他们在\(fail\)树上对应节点 ...
- 「雅礼集训 2017 Day2」解题报告
「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...
- 「雅礼集训 2017 Day1」 解题报告
「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...
- [LOJ 6031]「雅礼集训 2017 Day1」字符串
[LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...
- [LOJ 6030]「雅礼集训 2017 Day1」矩阵
[LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...
- [LOJ 6029]「雅礼集训 2017 Day1」市场
[LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...
随机推荐
- AC日记——砝码称重 洛谷 P2347
题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入输出格式 输入格式: 输入方式:a1 a2 a3 a4 a5 a6 (表示1g砝码有a1个,2g砝 ...
- HNOI_2002 营业额统计(Splay)
此题可以用STL的multiset解决,也可以手打一棵伸展树(Splay)来求前驱与后驱. 使用multiset: #include<iostream> #include<set&g ...
- BZOJ1017魔兽地图DotR 樹形DP
@(BZOJ)[樹形DP, 三維DP] Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA ...
- iOS--基于键值的观察者模式(KVO)
VO简而言之就是:基于键值的观察者,实际上就是观察者模式. Cocoa Framework已经为我们提供了这一模式,不需要我们自己来实现了.我们只需要按照约定的方式去做就可以了.KVO主要用于用户界面 ...
- docker日志输出文件大小设置以及文件个数限制
问题描述: 今天有同事运行了一个docker容器,不多时就导致宿主机硬盘直接撑爆,消耗了120G,发生的很是突然. 问题排查: 后续查阅资料,发现是因为docker中的某个进程一直在持续输出,而这些输 ...
- 数据库系统学习(七)-SQL语言之复杂查询与视图
第七讲 SQL语言之复杂查询与视图 基本内容 子查询 IN与NOT IN谓词子查询 判断某一表达式的值是否在子查询的结构中 非相关子查询 相关子查询 theta some /theta all谓词子查 ...
- Hbase调用JavaAPI实现批量导入操作
将手机上网日志文件批量导入到Hbase中.操作步骤: 1.将日志文件(请下载附件)上传到HDFS中,利用hadoop的操作命令上传:hadoop fs -put input / 2.创建Hbase ...
- BUPT复试专题—数据库检索(2014软院)
题目描述 在数据库的操作过程中,我们进场会遇到检索操作.这个题目的任务是完成一些特定格式的检索,并输出符合条件的数据库中的所有结果. 我们现在有一个数据库,维护了学生的姓名(Name),性别(Sex) ...
- BUPT复试专题—串查找(?)
https://www.nowcoder.com/practice/a988eda518f242c29009f8620f654ede?tpId=67&tqId=29642&rp=0&a ...
- 《python源代码剖析》笔记 Python的编译结果
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.python的运行过程 1)对python源码进行编译.产生字节码 2)将编译结果交给p ...