您的位置:首页 > 其它

HDU 5862 Counting Intersections

2016-08-20 11:15 267 查看
题意: 问与坐标轴平行的这些线段有多少个交点。

思路: 线扫描的思想,这种做法也是很好想的。

由于坐标的范围较大,可将其中一个坐标离散化(我是离散化X坐标)。

由于题目中有声明:The input data guarantee that no two segments share the same endpoint, no covered segments, and no segments with length 0.

所有没什么坑点。

具体的: 我是将x坐标进行离散化。对于每条边,如果与y轴平行,我分别记录该点的上点和下点,上点标记为-1,下点标记为1,如果是与x平行的边,就直接记录改变,并标记为0;然后对这些点按照y坐标进行排序。 接着就该是加点(边)的操作了。当该点标记为0,就算出(x1,x2)s的和.如果不是0,则在s的x1点加上它的标记。

代码如下:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<iostream>
#include<complex>
#include<string>
#include<set>
#include<map>
#include<algorithm>
//#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define nn 100100
#define mm 2000200
#define ll long long
#define ULL unsiged long long
#define pb push_back
#define mod 1000000007
#define inf 0xfffffffffff
#define eps 0.00000001

struct node
{
int x1, y, x2;
int idx;
}ax[mm];
int posx[mm], s[mm];
bool cmp(node a, node b)
{
if(a.y!=b.y) return a.y < b.y;
else return a.idx > b.idx;
}

int lowbit(int x)
{
return x&(-x);
}
void add(int x,int val,int n)
{
while (x <= n)
{
s[x]+=val;
x += lowbit(x);
}
}

int sum(int x)
{
int ans = 0;
while (x)
{
ans += s[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
int t;//t = io.xint();
scanf("%d", &t);
while (t--)
{
int n;//n = io.xint();
scanf("%d", &n);
int nx = 0, ny = 0;
for (int i = 0; i < n; i++)
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
//x1 = io.xint(); y1 = io.xint();
//x2 = io.xint(); y2 = io.xint();
if (x1 > x2) swap(x1, x2);
if (y1 > y2) swap(y1, y2);
posx[ny++] = x1;
posx[ny++] = x2;
if (x1 == x2)
{
ax[nx].x1 = x1; ax[nx].y = y1;
ax[nx++].idx = 1;
ax[nx].x1 = x1; ax[nx].y = y2;
ax[nx++].idx = -1;
}
else
{
ax[nx].x1 = x1; ax[nx].x2 = x2; ax[nx].y = y1;
ax[nx++].idx = 0;
}
}
sort(posx, posx+ny);
int lenx = unique(posx, posx + ny) - posx;
sort(ax, ax + nx, cmp);
memset(s, 0, sizeof(s));
ll ans = 0;
for (int i = 0; i < nx; i++)
{
if (ax[i].idx == 0)
{
int l = lower_bound(posx, posx + lenx, ax[i].x1) - posx + 1;
int r = lower_bound(posx, posx + lenx, ax[i].x2) - posx + 1;
ans +=(ll) sum(r) - sum(l - 1);
}
else
{
int l = lower_bound(posx, posx + lenx, ax[i].x1) - posx + 1;
add(l, ax[i].idx, lenx + 1);
}
}
printf("%lld\n", ans);
}
return 0;
}记住:要用ll 答案是会超int的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线扫描