题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5480
这道题其实如果理解了题目还是蛮简单的,ac也不难,不过博主一开始没理解好题目,超时worry answer不断。
先分析一下题目,如果某个区域可以完全被打到,那么需要的是什么呢?仅仅只需要在x轴或y轴上布满坦克就好了,任意满足一个就可以,可是楼主在正确理解这以后开始写代码居然超时了,应为我是每输入一个矩形数据就去矩阵中查找,在这一段中是不是有某条边满足连续存在坦克的情况,但是因为数据量很大,一个完整的矩形可能达到非常大的数,而挨个查的话势必要遍历完整个矩形才可以,这种暴力的方法显然是行不通的。
后来我改变方法,把矩形记录了下来,水过了,不过仔细看了看sd0061的解题思路忽然就觉得自己的方法逊爆了,同样是利用某种方法保存覆盖的情况,但他使用的是一种前缀和的思路,将矩形的x,y轴依次遍历一遍,利用两个数组,将某一个点的值设为前面所有的这个轴上的坦克的数量,比如x轴上1,2,8位置有坦克,y轴我们不管,那么我们对应x轴的数组,叫A好了,A【1】==1,A[2]==2,A[3-7]==2,A[8]==3,这样子是什么意义呢,两个值之间的差就代表了这两个点之间的坦克数量,x位置8和5的值减一下A[8]-A[5]==1,而8-5==3,很容易判断出8与5之间坦克不在x轴上布满,非常好的思路,虽然这道题不难,但这个前缀和的思路还是很好的,而且网上查了一下,应该还和并行计算有点关系,有兴趣的同学可以研究一下。
最后上代码,因为种种关系楼主自己的垃圾代码就不上了,bc都过了一周才写这篇博客真是惭愧,虽说也不一定有人看。。。。
不过努力吧
代码来自http://blog.csdn.net/u012717411/article/details/48811481
也是一篇很好的讲解系博客,而且从文章来看,博主Hacker_vision还是一个文艺青年
//P.S 很多acmer使用博客发解题报告,一般这样子坚持下去的话
//文章基本过百没问题,这本来也是个不错的事情,不过因为个人原因
//博主认为那些纯粹发个题目在发个code的毫无讲解性质的文章
//多多少少有些凑字数的感觉,毕竟ac之后复制一下也就几秒钟的时间
// 而且很多acm的代码因为各种限制问题,经常写起来,非常难看,
//当然这是必然的,就好像博主高中数学考试的字也是非常恶心的
// 不过博主保证不会发这种有刷分嫌疑的acm报告,虽然楼主烂的一B
// 借今天小小的吐槽一下,当然那些acmer刷题的精神还是非常可敬的
// 最后一点不得不吐槽 sd0061居然是个小圆迷,所有题目都是小圆的歌曲
// 直接导致我听了一小时的歌才开始看别人的解题报告
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const int _max = 1e5 + 10;
int n,m,k,Q,row[_max],col[_max];
int x,y;
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
int T;cin>>T;
while(T--){
fill(row,row+_max,0);
fill(col,col+_max,0);
scanf("%d%d%d%d",&n,&m,&k,&Q);
while(k--){
scanf("%d%d",&x,&y);
row[x] = 1;
col[y] = 1;
}
for(int i = 2; i <= n; ++ i)
row[i] += row[i-1];
for(int j = 2; j<= m; ++ j)
col[j] += col[j-1];
int x1,x2,y1,y2;
for(int i = 0; i < Q; ++ i){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(row[x2]-row[x1-1] == x2 - x1 + 1||col[y2]-col[y1-1]==y2-y1+1) puts("Yes");
else puts("No");
}
}
return 0;
}