描述
小王最近在开发一种新的游戏引擎,但是最近遇到了性能瓶颈。于是他打算从最基本的画线功能开始分析优化。画线其实就是调用一次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; }