网易互娱2017实习生招聘在线笔试第一场-题目3
来源:互联网 发布:javascript 最新版本 编辑:程序博客网 时间:2024/04/30 13:31
题目3 : 画线
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
- 样例输入
243 8 6 8-3 8 1 82 3 4 53 4 6 751 1 2 22 2 3 33 3 4 24 2 5 11 0 100 0
- 样例输出
33
描述
小王最近在开发一种新的游戏引擎,但是最近遇到了性能瓶颈。于是他打算从最基本的画线功能开始分析优化。画线其实就是调用一次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。
输出
对于每个测试点,对应的结果输出一行,表示最少用多少次指令即可完成所有的画线。
思路分析:
每条线段有两个点,一个起始点,一个终止点,用一个结构体表示。每条直线都有斜率,将其算出存放在结构体当中,判断条件为两条直线斜率相同且端点之间存在包含关系。
代码:
三个函数:dealpiont处理输入点的初始化,dealine负责寻找有重复点的线段,mergeline负责将dealline中重复线段合并。
#include <iostream>#include <vector>#include <stdio.h>using namespace std;struct piont{ int x_l; int x_h; int y_l; int y_h; int ori ;//保存直线的方向 piont(int a,int b,int c,int d) { x_l = a; x_h = c; y_l = b; y_h = d; if(b == d) ori = 1; else if(a == c) ori = 2; else if(d > b) ori = 3; else ori = 4; }};vector<piont> PNV;void mergeline(vector<piont>::iterator it,vector<piont>::iterator next)//将两条重叠的线合并{ if(it->ori==1) { it->x_l = (it->x_l<next->x_l)?it->x_l:next->x_l; it->x_h = (it->x_h>next->x_h)?it->x_h:next->x_h; } else if(it->ori==2) { it->y_l = (it->y_l<next->y_l)?it->y_l:next->y_l; it->y_h = (it->y_h>next->y_h)?it->y_h:next->y_h; } else if(it->ori==3) { it->x_l = (it->x_l<next->x_l)?it->x_l:next->x_l; it->x_h = (it->x_h>next->x_h)?it->x_h:next->x_h; it->y_l = (it->y_l<next->y_l)?it->y_l:next->y_l; it->y_h = (it->y_h>next->y_h)?it->y_h:next->y_h; } else { it->x_l = (it->x_l<next->x_l)?it->x_l:next->x_l; it->x_h = (it->x_h>next->x_h)?it->x_h:next->x_h; it->y_l = (it->y_l>next->y_l)?it->y_l:next->y_l; it->y_h = (it->y_h<next->y_h)?it->y_h:next->y_h; } PNV.erase(next);}void dealline(vector<piont>::iterator it,int x_a,int y_a)//查找相重叠的线{ for(auto next=it+1;next!=PNV.end();next++) { if(it->ori==next->ori)//两条线的方向要一致。 { int temp_x = it->x_l; int temp_y = it->y_l; while(temp_x!=it->x_h)//第一条线没到头 { if(temp_x==next->x_l||temp_x==next->x_h)//两条线相遇了 { mergeline(it,next); return; } temp_x +=x_a;//活动点延斜率方向移动 temp_y +=y_a; } } }}void dealpiont(){ int n; cin >> n; for(int i=0;i<n;i++) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,& d); piont p(a,b,c,d) ; PNV.push_back(p); } for(auto i=PNV.begin();i!=PNV.end();i++) { switch(i->ori)//根据斜率决定每次移动的步数 { case 1: dealline(i,1,0); break; case 2: dealline(i,0,1); break; case 3: dealline(i,1,1); break; case 4: dealline(i,1,-1); break; } } for(auto i=PNV.begin();i!=PNV.end();i++) { cout << i->x_l << " " << i->y_l << " " << i->x_h << " " << i->y_h << " " << i->ori << endl; } cout << PNV.size() << endl;}int main(){ int c; cin >> c; while(c--) { dealline(); PNV.clear();//清空vector } return 0;}
0 0
- 网易互娱2017实习生招聘在线笔试第一场-题目3
- 网易互娱2017实习生招聘在线笔试第一场 题目1 : 电子数字
- 网易互娱2017实习生招聘在线笔试第一场题目解析
- 网易互娱2017实习生招聘在线笔试第一场-3划线
- 网易互娱2017实习生招聘在线笔试第一场-1电子数字
- 网易互娱2017实习生招聘在线笔试第一场-2源代码编译
- 网易互娱2017实习生招聘在线笔试第一场-电子数字
- 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场(图像处理)
- 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场(神奇的数)
- 易互娱2017实习生招聘在线笔试第一场题目1 : 电子数字
- 网易互娱2017实习生招聘在线笔试(一)
- 网易互娱2017实习生招聘在线笔试(二)
- 网易互娱2017实习生招聘在线笔试(三)
- 网易互娱2017实习生招聘在线笔试(一)
- 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场(一起消消毒)
- 网易游戏2016实习生招聘在线笔试——题目1 : 推箱子
- 网易游戏2016实习生招聘在线笔试 推箱子
- 网易游戏2016实习生招聘在线笔试:A 推箱子
- org.hibernate.HibernateException: connnection proxy not usable after transaction
- jQuery异步框架探究1:jQuery._Deferred方法
- [阿里笔试] 2016阿里校招业务性产品经理(商业领域)笔试题
- 针对TQ部分ARM开发板中QTCPServer不能接受数据的问题
- webdriver报不可见元素异常方法总结
- 网易互娱2017实习生招聘在线笔试第一场-题目3
- 整理的一些常用的Java日期时间上面的操作
- HttpClient4.X Invalid use of SingleClientConnManager: connection still allocated
- retrofit 如何查看日志
- java 小结 (四)
- Invalid use of BasicClientConnManager: connection still allocated.
- Dubbo学习(六):多注册中心
- HttpsURLConnection
- java 实现两个日期之间所有日期的遍历