P1830 轰炸III
轰炸III
题目背景
一个大小为 \(n\times m\) 的城市遭到了 \(x\) 次轰炸,每次都炸了一个每条边都与边界平行的矩形。
题目描述
在轰炸后,有 \(y\) 个关键点,指挥官想知道,它们有没有受到过轰炸,如果有,被炸了几次,最后一次是第几轮。
输入格式
第一行共四个整数,分别为 \(n,m,x,y\)。
接下来 \(x\) 行,每行四个整数 \(x_1,y_1,x_2,y_2\),表示被轰炸的矩形的左上角坐标和右下角坐标(比如 \(1,3,7,10\) 就表示被轰炸的地方是从 \((1,3)\) 到 \((7,10)\) 的矩形)。
接下来 \(y\) 行,每行两个整数,表示这个关键点的坐标。
输出格式
输出共 \(y\) 行,每行第一个字符为 Y
或 N
,表示是否被轰炸;若为 Y
,在一个空格后为两个整数,表示被炸了几次和最后一次是第几轮。
样例 #1
样例输入 #1
10 10 2 3
1 1 5 5
5 5 10 10
3 2
5 5
7 1
样例输出 #1
Y 1 1
Y 2 2
N
提示
对于 \(100\%\) 数据,满足 \(1\le n,m\le 100\)。
我的代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct zone
{
int x1;
int y1;
int x2;
int y2;
} Zone;
typedef struct point
{
int x;
int y;
} Point;
typedef struct result
{
char p;
int m;
int n;
} Result;
int main()
{
int n, m, x, y;
scanf("%d %d %d %d", &n, &m, &x, &y);
Zone *zones = (Zone *)malloc(n * sizeof(Zone));
Point *points = (Point *)malloc(n * sizeof(Point));
Result *results = (Result *)malloc(n * sizeof(Result));
//内存申请失败的情况
if (zones == NULL || points == NULL || results == NULL)
{
printf("内存申请失败");
return 1;
}
// 变长数组(Variable Length Arrays,VLA)不能在声明时进行初始化
// Zone zones[n] = {0};
// Point points[m] = {0};
// 但可以使用memset清零
//以下写法错误
//在C语言中,结构体数组的大小必须在编译时确定。这意味着你不能在运行时根据变量来定义结构体数组的大 小.这是因为栈上的数组需要在编译时知道其大小,因此数组的大小必须是一个常量表达式。
// Zone zones[x];
// Point points[y];
// Result results[x];
memset(zones, 0, sizeof(Zone) * x);
memset(points, 0, sizeof(Point) * y);
memset(results, 0, sizeof(Result) * x);
for (int i = 0; i < x; i++)
{
scanf("%d %d %d %d", &zones[i].x1, &zones[i].y1, &zones[i].x2, &zones[i].y2);
}
for (int j = 0; j < y; j++)
{
scanf("%d %d", &points[j].x, &points[j].y);
results[j].p = 'N';
results[j].m = 0;
results[j].n = 0;
for (int i = 0; i < x; i++)
{
if (points[j].x <= zones[i].x2 && points[j].x >= zones[i].x1 && points[j].y <= zones[i].y2 && points[j].y >= zones[i].y1)
{
results[j].p = 'Y';
results[j].m++;
results[j].n = i;
}
}
}
for (int j = 0; j < y; j++)
{
if (results[j].m == 0)
{
printf("%c\n", 'N');
}
else
{
//这里由于是从零开始计数,所以实际的最后一次轰炸次数要+1
printf("%c %d %d\n", results[j].p, results[j].m, results[j].n + 1);
}
}
//要记得释放申请的空间
free(zones);
free(points);
free(results);
return 0;
}
题解
主要思路:
1、用mp二维数组存下地图
2、算出被轰炸的范围:(x1~x2,y1~y2)
3、将被轰炸过的坐标++,用于输出被轰炸过的次数;并用final数组记录每个被轰炸过的坐标的最后一次轰炸
4、如果坐标为0,说明没有被轰炸,输出“N”并换行;如果坐标不为0,说明已被轰炸,输出“Y ”、被轰炸的次数、“ ”、该坐标的最后一次轰炸并换行
AC代码--
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,x,y,final[110][110];
int x1,y1,x2,y2;
int checkx,checky;
int mp[110][110];
memset(mp,0,sizeof(mp));
memset(final,0,sizeof(final));
cin>>n>>m>>x>>y;
for(int i=1;i<=x;i++){
cin>>x1>>y1>>x2>>y2;
for(int j=x1;j<=x2;j++){
for(int k=y1;k<=y2;k++){
mp[j][k]++;
final[j][k]=i;
}
}
}
for(int i=1;i<=y;i++){
cin>>checkx>>checky;
if(mp[checkx][checky]==0)
cout<<"N"<<endl;
else
cout<<"Y "<<mp[checkx][checky]<<" "<<final[checkx][checky]<<endl;
}
return 0;
}