企业级在线家具商城设计与实现pf管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】
(新卷,100分)- 多段线数据压缩Java JS Python C题目描述下图中每个方块代表一个像素每个像素用其行号和列号表示。
为简化处理多线段的走向只能是水平、竖直、斜向45度。
上图中的多线段可以用下面的坐标串表示(2,
,(3,
,(3,
,(3,
,(4,
,(5,
,(6,
,(7,
,(8,
,(7,
。
但可以发现这种表示不是最简的其实只需要存储6个蓝色的关键点即可它们是线段的起点、拐点、终点而剩下4个点是冗余的。
现在请根据输入的包含有冗余数据的多线段坐标列表输出其最简化的结果。
输入描述2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5所有数字以空格分隔每两个数字一组第一个数字是行号第二个数字是列号行号和列号范围 为 [0,
用例输入保证不会越界考生不必检查输入数据至少包含两个坐标点输出描述2 8 3 7 3 5 6 2 8 4 7 5压缩后的最简化坐标列表和输入数据的格式相同。
备注输出的坐标相对顺序不能变化用例输入2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5输出2 8 3 7 3 5 6 2 8 4 7 5说明如上图所示6个蓝色像素的坐标依次是(2,
、(3,
、(3,
、(6,
、(8,
、(7,
将他们按顺序输出即可。
题目解析本题其实就是要我们保留拐点。
那么怎么判断一个点是不是拐点呢拐点拐点自然是运动方向发生改变的点。
那么如何判断一个点的运动方向呢运动指的是从点A到点B而运动的方向自然是点A到点B的方向。
那么如何描述点A到点B的方向呢假设点A2, 8点B3 7那么此时点A到点B的偏移量为offsetX 3 - 2 1offsetY 7 - 8 -1则offsetX, offsetY就是A→B的向量坐标。
当然还有可能出现这样的情况比如A坐标3,5B坐标6,2此时A→B向量坐标为3, -3此时3,-3向量的方向其实和1,-1是相同的。
因此我们需要对这种向量做简化方便后续相同方向的比较即将3,-3简化为1,-1字面上看其实就是横坐标、纵坐标都除以3那么base3该如何求解呢求解公式如下base max(abs(offsetX), abs(offsetY))这个公式的好处是兼容(-5,
(0,
这种向量。
当我们知道了A→B的方向那么只要判断下一步B→C的方向是否发生改变如果发生改变那么就可以确定B是拐点比如A→B的向量为-1, 0B→C的向量为-1, 0因此B不是拐点B→C的向量为-1, 0C→D的向量为1, -1因此C是拐点JS算法源码const rl require(readline).createInterface({ input: process.stdin }); var iter rl[Symbol.asyncIterator](); const readline async () (await iter.next()).value; void (async function () { const nums (await readline()).split( ).map(Number); console.log(getResult(nums)); })(); function getResult(nums) { const ans []; // 上一个点坐标preX, preY let preX nums[0]; let preY nums[1]; // 上一次的运动方向preDirectX, preDirectY let preDirectX 0; let preDirectY 0; for (let i 2; i nums.length; i
{ // 当前点坐标curX, curY const curX nums[i]; const curY nums[i 1]; // 上一个点到当前点的偏移量offsetX, offsetY const offsetX curX - preX; const offsetY curY - preY; // 根据偏移量得出本次的运动方向 const base Math.max(Math.abs(offsetX), Math.abs(offsetY)); const directX offsetX / base; const directY offsetY / base; // 如果两次运动的方向不同 if (directX ! preDirectX || directY ! preDirectY) { // 则上一个点是拐点需要记录下来 ans.push(preX, preY); } preX curX; preY curY; preDirectX directX; preDirectY directY; } // 注意收尾 ans.push(preX, preY); return ans.join( ); }Java算法源码import java.util.Arrays; import java.util.Scanner; import java.util.StringJoiner; public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); int[] nums Arrays.stream(sc.nextLine().split( )).mapToInt(Integer::parseInt).toArray(); System.out.println(getResult(nums)); } public static String getResult(int[] nums) { StringJoiner sj new StringJoiner( ); // 上一个点坐标preX, preY int preX nums[0]; int preY nums[1]; // 上一次的运动方向preDirectX, preDirectY int preDirectX 0; int preDirectY 0; for (int i 2; i nums.length; i
{ // 当前点坐标curX, curY int curX nums[i]; int curY nums[i 1]; // 上一个点到当前点的偏移量offsetX, offsetY int offsetX curX - preX; int offsetY curY - preY; // 根据偏移量得出本次的运动方向 int base Math.max(Math.abs(offsetX), Math.abs(offsetY)); int directX offsetX / base; int directY offsetY / base; // 如果两次运动的方向不同 if (directX ! preDirectX || directY ! preDirectY) { // 则上一个点是拐点需要记录下来 sj.add(preX preY); } preX curX; preY curY; preDirectX directX; preDirectY directY; } // 注意收尾 sj.add(preX preY); return sj.toString(); } }Python算法源码# 输入获取 nums list(map(int, input().split())) # 算法入口 def getResult(): ans [] # 上一个点坐标preX, preY preX nums[0] preY nums[1] # 上一次的运动方向preDirectX, preDirectY preDirectX 0 preDirectY 0 for i in range(2, len(nums),
: # 当前点坐标curX, curY curX nums[i] curY nums[i 1] # 上一个点到当前点的偏移量offsetX, offsetY offsetX curX - preX offsetY curY - preY # 根据偏移量得出本次的运动方向 base max(abs(offsetX), abs(offsetY)) directX offsetX // base directY offsetY // base # 如果两次运动的方向不同 if directX ! preDirectX or directY ! preDirectY: # 则上一个点是拐点需要记录下来 ans.extend([preX, preY]) preX curX preY curY preDirectX directX preDirectY directY # 注意收尾 ans.extend([preX, preY]) return .join(map(str, ans)) # 算法调用 print(getResult())C算法源码#include stdio.h #include math.h #define MAX_SIZE 20000 int main() { int nums[MAX_SIZE]; int nums_size 0; while (scanf(%d, nums[nums_size])) { if (getchar() ! ) break; } // 上一个点坐标preX, preY int preX nums[0]; int preY nums[1]; // 上一次的运动方向preDirectX, preDirectY int preDirectX 0; int preDirectY 0; for (int i 2; i nums_size; i
{ // 当前点坐标curX, curY int curX nums[i]; int curY nums[i 1]; // 上一个点到当前点的偏移量offsetX, offsetY int offsetX curX - preX; int offsetY curY - preY; // 根据偏移量得出本次的运动方向 int base (int) fmax(abs(offsetX), abs(offsetY)); int directX offsetX / base; int directY offsetY / base; // 如果两次运动的方向不同 if (directX ! preDirectX || directY ! preDirectY) { // 则上一个点是拐点需要记录下来 printf(%d %d , preX, preY); } preX curX; preY curY; preDirectX directX; preDirectY directY; } // 注意收尾 printf(%d %d, preX, preY); return 0; }
彩虹版gtv全球最好g平台-彩虹版gtv全球最好g平台应用