描述
小王最近在開發一種新的游戲引擎,但是最近遇到了性能瓶頸。於是他打算從最基本的畫線功能開始分析優化。畫線其實就是調用一次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;
}
