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\) 行,每行第一个字符为 YN,表示是否被轰炸;若为 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;
}
posted @ 2023-07-28 01:56  DawnTraveler  阅读(70)  评论(0编辑  收藏  举报