前言
模拟算法的核心思想是枚举,即把所有可能的情况都罗列出来,从中找出符合题目要求的那一个。虽然这是一种暴力方法,容易超时,但在数据范围允许的情况下,它是最直接的解法。
使用枚举策略时,重点思考三个问题:枚举的对象是什么?枚举的顺序如何(正序还是逆序)?以及枚举的方式(普通循环、递归还是二进制)。
一、铺地毯
题目描述 给定 n 张地毯,每张地毯由左下角坐标 (x, y) 和长宽 g, k 定义。查询某个位置 (X, Y) 被哪一张地毯覆盖。如果有多个,输出最后放置的那一张。
思路解析 我们需要找到覆盖 (X, Y) 的地毯中编号最大的那个。如果从前往后枚举,必须遍历完所有地毯才能确定结果。更优的做法是逆序枚举:从最后一张地毯开始往前找,第一次遇到覆盖该位置的地毯,就是答案。
代码实现
#include<iostream>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL a[N], b[N], g[N], k[N];
int n;
int find_pos(int x, int y){
for(int i = n; i >= 1; i--){
// 判断是否覆盖
if(x >= a[i] && y >= b[i] && x <= a[i] + g[i] && y <= b[i] + k[i])
return i;
}
return -1;
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i] >> b[i] >> g[i] >> k[i];
LL x, y;
cin >> x >> y;
cout << find_pos(x, y) << endl;
return 0;
}
二、回文日期
题目描述 给定两个日期 begin 和 end,统计区间内有多少个回文日期。


