题目链接:
题目大意:两条退垂直于x轴的直线,y没有限制,给出几条y=kx+b的直线,求这些直线将两条线之间的区域分割成几块儿。
解题思路:经过研究(多试几次是好了)结果=直线数+交点数+1。所以重点就变成了求交点的个数,从大牛们的博客中看到用逆序数求交点个数,顿时感觉好牛,有木有!!
过程是这样的:对每一条直线的输入求出与给定两条直线的交点纵坐标,对其中一个按y值排序,然后再对另一边的y值归并排序,利用在左边的编号求出逆序数,这个逆序数就是交点数,原理画图很容易得到,就不冗述了。
下面直接上代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
struct Line {
int y1;
int y2;
}L[30000], buf[30000];
int ans;
int x_l, x_r;
bool cmp(const Line& l1, const Line& l2) {
return l1.y1 < l1.y2;
}
void marge_sort(int b, int e){
if(b == e) return;
int mid = (b+e) / 2;
marge_sort(b, mid);
marge_sort(mid+1, e);
int i = b;
int pos = b;
int j = mid+1;
while(i <= mid && j <= e) {
while(L[i].y2 <= L[j].y2 && i <= mid)
buf[pos++] = L[i++];
while(L[j].y2 < L[i].y2 && j <= e) {
buf[pos++] = L[j++];
ans += mid + 1 - i;
}
}
while(i <= mid) buf[pos++] = L[i++];
while(j <= e) buf[pos++] = L[j++];
for(int i = b; i <= e; i++) {
L[i] = buf[i];
}
}
int main() {
// freopen("data.in", "r", stdin);
int n, k, b;
while(~scanf("%d%d", &x_l, &x_r)) {
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d%d", &k, &b);
L[i].y1 = k * x_l + b;
L[i].y2 = k * x_r + b;
}
sort(L, L+n, cmp);
ans = 0;
marge_sort(0, n-1);
printf("%d\n", ans+n+1);
}
return 0;
}