描述
小王最近在开发一种新的游戏引擎,但是最近遇到了性能瓶颈。于是他打算从最基本的画线功能开始分析优化。画线其实就是调用一次drawline命令,根据给出的两端坐标,在屏幕画出对应的线段。但是小王发现,很多的drawline其实可以合并在一起,譬如下图中的线段(2,3)-(4,5)和线段(3,4)-(6,7),其实可以合并为一次drawline命令,直接画出线段(2,3)-(6,7)。当然有些线段是无法合并的,如线段(-3,8)-(1,8)和线段(3,8)-(6,8),就必须调用两次drawline命令。

给出N条drawline指令以及对应的线段坐标,小王想知道,实际最少用多少次drawline指令就可以画出来。
小王想先从最简单的情况开始分析优化,所以线段只包含四种情况:水平线段,垂直线段以及正反45度的线段。
输入
每个输入数据包含多个测试点。
第一行为测试点的个数 S ≤ 10。之后是 S 个测试点的数据。
每个测试点的第一行为 N(N ≤ 105)。之后是 N 行,每行包含4个整数:x0, y0, x1, y1,表示线段(x0,y0)-(x1,y1),坐标的范围在[-108, 108],保证线段的长度大于0。
输出
对于每个测试点,对应的结果输出一行,表示最少用多少次指令即可完成所有的画线。
样例输入
2 4 3 8 6 8 -3 8 1 8 2 3 4 5 3 4 6 7 5 1 1 2 2 2 2 3 3 3 3 4 2 4 2 5 1 1 0 100 0
样例输出
3 3
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Line
{
int x0;
int y0;
int x1;
int y1;
int x; // 排序用的
double b; // 截距
/* bool operator <(const Line& ln)
{
if(b==ln.b)
{
if(x<ln.x)
{
return true;;
}
else
{
return false;
}
}
else if(b<ln.b)
{
return true;
}
else
{
return false;
}
}*/
};
bool CompLine(const Line& ll,const Line& ln)
{
if(ll.b==ln.b)
{
if(ll.x<ln.x)
{
return true;;
}
else
{
return false;
}
}
else if(ll.b<ln.b)
{
return true;
}
else
{
return false;
}
}
int main()
{
int S,N;
int x0,y0,x1,y1,dx,dy;
vector<Line> vh;
vector<Line> vv;
vector<Line> vs;
vector<Line> vr;
cin>>S;
while(S--)
{
vh.clear();
vv.clear();
vs.clear();
vr.clear();
cin>>N;
for(int i=0; i<N; i++)
{
cin>>x0>>y0>>x1>>y1;
dx=x1-x0;
dy=y1-y0;
if(dy==0) //水平线段
{
Line lh;
if(dx>0)
{
lh.x0=x0;
lh.x1=x1;
lh.y0=y0;
lh.y1=y1;
}
else
{
lh.x0=x1;
lh.x1=x0;
lh.y0=y1;
lh.y1=y0;
}
lh.x=lh.x0;
lh.b=lh.y0;
vh.push_back(lh);
}
else if(dx==0) //垂直线段
{
Line lv;
if(dy>0)
{
lv.x0=x0;
lv.x1=x1;
lv.y0=y0;
lv.y1=y1;
}
else
{
lv.x0=x1;
lv.x1=x0;
lv.y0=y1;
lv.y1=y0;
}
lv.x=lv.y0;
lv.b=lv.x0;
vv.push_back(lv);
}
else if(dx==dy) //斜率1
{
Line ls;
if(dx>0)
{
ls.x0=x0;
ls.y0=y0;
ls.x1=x1;
ls.y1=y1;
}
else
{
ls.x0=x1;
ls.y0=y1;
ls.x1=x0;
ls.y1=y0;
}
ls.x=ls.x0;
ls.b=ls.y0-ls.x0;
vs.push_back(ls);
}
else //斜率-1
{
Line lr;
if(dx>0)
{
lr.x0=x0;
lr.y0=y0;
lr.x1=x1;
lr.y1=y1;
}
else
{
lr.x0=x1;
lr.y0=y1;
lr.x1=x0;
lr.y1=y0;
}
lr.x=lr.x0;
lr.b=lr.x0+lr.y0;
vr.push_back(lr);
}
}
sort(vh.begin(),vh.end(),CompLine);
sort(vv.begin(),vv.end(),CompLine);
sort(vs.begin(),vs.end(),CompLine);
sort(vr.begin(),vr.end(),CompLine);
//合并
vector<Line>::iterator ih=vh.begin();
vector<Line>::iterator in;
for(; ih!=vh.end();)
{
in= ih;
in++;
if(in!=vh.end())
{
if((*ih).b==(*in).b)
{
if((*in).x0<=(*ih).x1) //相交
{
(*in).x0=(*ih).x0;
if((*in).x1<(*ih).x1)
{
(*in).x1=(*ih).x1;
}
ih=vh.erase(ih);
continue;
}
}
}
ih++;
}
vector<Line>::iterator iv=vv.begin();
for(; iv!=vv.end();)
{
in= iv;
in++;
if(in!=vv.end())
{
if((*iv).b==(*in).b)
{
if((*in).y0<=(*iv).y1) //相交
{
(*in).y0=(*iv).y0;
if((*in).y1<(*iv).y1)
{
(*in).y1=(*iv).y1;
}
iv=vv.erase(iv);
continue;
}
}
}
iv++;
}
ih=vs.begin();
for(; ih!=vs.end();)
{
in= ih;
in++;
if(in!=vs.end())
{
if((*ih).b==(*in).b)
{
if((*in).x0<=(*ih).x1) //相交
{
(*in).x0=(*ih).x0;
(*in).y0=(*ih).y0;
if((*in).x1<(*ih).x1)
{
(*in).x1=(*ih).x1;
(*in).y1=(*ih).y1;
}
ih=vs.erase(ih);
continue;
}
}
}
ih++;
}
ih=vr.begin();
for(; ih!=vr.end();)
{
in= ih;
in++;
if(in!=vr.end())
{
if((*ih).b==(*in).b)
{
if((*in).x0<=(*ih).x1) //相交
{
(*in).x0=(*ih).x0;
(*in).y0=(*ih).y0;
if((*in).x1<(*ih).x1)
{
(*in).x1=(*ih).x1;
(*in).y1=(*ih).y1;
}
ih=vr.erase(ih);
continue;
}
}
}
ih++;
}
int cnt=vh.size()+vv.size()+vs.size()+vr.size();
cout << cnt<< endl;
}
return 0;
}
