1.有一个水平放置的矩形纸箱,现希望用隔板把这个纸箱分割成很多小的格子,每个格子都可以放下若干个物品。从上往下看的效果如下图所示。已知纸箱左上角和右下角的坐标以及每个隔板放入纸箱后的位置坐标。现有若干个物品,已知物品放入纸箱后的位置,求每个格子中有多少个物品?
输入描述:
输入的第一行包含6个整数,分别是n(0<n<=5000),m(0<m<=5000),x1,y1,x2,y2,分别表示隔板的数量,物品的数量,矩形纸箱左上角点的坐标和右下角点的坐标(从上往下看投影到XY平面的坐标),其后有n行,分别表示隔板的位置,按从左到右的顺序排列,且各个隔板互不相交。每一行有两个整数,Ui和Li,表示第i个隔板的位置坐标在(Ui,y1)和(Li,y2)。其后的m行,每一行有两个整数,Xj 和Yj,分别表示物品的位置。物品不可能正好在隔板上,也不可能在箱子外。
输出描述:
输出n+1行,每一行的形式为:k:h。其中k表示格子的编号,最左边的格子为0,依次递增,最右边的格子为n;h为第k个格子中物品的数量。
样例输入:
5 6 0 10 60 0
3 1
4 3
6 8
10 10
15 30
1 5
2 1
2 8
5 5
40 10
7 9
样例输出:
0: 2
1: 1
2: 1
3: 1
4: 0
5: 1
声明:本系列所有作业以及实验均只给出代码。
#include <iostream>
using namespace std;
// 物品坐标
typedef struct Point{
int x{}, y{};
}Point;
// 边界线
typedef struct Board{
Point up{}, low{};
// 斜率
float k = 0;
}Board;
/**
* @brief 该函数采用的知识为线性规划
* 即y > k(x - x0) + y0 || y < k(x - x0) + y0
* 若输出true则点在板的左边,否则在右边
*/
inline bool check(Point location, Board board) {
if (board.k == 0) {
// 斜率为无穷的情况
return location.x < board.up.x;
} else if ((location.y > (board.k * (location.x - board.up.x) + board.up.y)) && (board.k > 0)) {
return true;
} else if ((location.y < (board.k * (location.x - board.up.x) + board.up.y)) && (board.k < 0)){
return true;
} else {
return false;
}
}
int main() {
int n, m;
int x1, x2, y1, y2;
// 输入部分
cin >> n >> m >> x1 >> y1 >> x2 >> y2;
Point items[m];
Board boards[n];
int counter[n + 1];
for (int i = 0; i < n; ++i) {
cin >> boards[i].up.x >> boards[i].low.x;
boards[i].up.y = y1;
boards[i].low.y = y2;
// 输入板坐标的同时计算板斜率
if (boards[i].up.x == boards[i].low.x) {
boards[i].k = 0;
} else {
boards[i].k = static_cast<float>(boards[i].up.y - boards[i].low.y) /
static_cast<float>(boards[i].up.x - boards[i].low.x);
}
// 初始化计数器
counter[i] = 0;
}
counter[n] = 0;
// 输入物品坐标
for (int i = 0; i < m; ++i) {
cin >> items[i].x >> items[i].y;
}
// 让每个点从左往右依次对板遍历
// 仅在板的输入为有序的情况下有效
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (check(items[i], boards[j])) {
counter[j]++;
break;
} else if (j == n - 1) {
counter[n]++;
}
}
}
for (int i = 0; i < n + 1; ++i) {
cout << i << ": " << counter[i] << endl;
}
return 0;
}
本算法时间复杂度为n方,仅供参考借鉴,欢迎大佬提供更快算法的思路。