Segment set(并查集 + 计算几何问题)

本文探讨了一种结合计算几何与并查集的数据结构问题,通过快速排斥实验和跨立实验来判断线段是否相交,并利用并查集维护线段集合的状态,最终求出特定线段集合的大小。

Segment set
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 253 Accepted Submission(s): 120

Problem Description
A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set.

Input
In the first line there is an integer t - the number of test case. For each test case in first line there is an integer n (n<=1000) - the number of commands.

There are two different commands described in different format shown below:

P x1 y1 x2 y2 - paint a segment whose coordinates of the two endpoints are (x1,y1),(x2,y2).
Q k - query the size of the segment set which contains the k-th segment.

k is between 1 and the number of segments in the moment. There is no segment in the plane at first, so the first command is always a P-command.

Output

        For each Q-command, output the answer. There is a blank line between test cases.

Sample Input
1
10
P 1.00 1.00 4.00 2.00
P 1.00 -2.00 8.00 4.00
Q 1
P 2.00 3.00 3.00 1.00
Q 1
Q 3
P 1.00 4.00 8.00 2.00
Q 2
P 3.00 3.00 6.00 -2.00
Q 5

Sample Output
1
2
2
2
5
/*
这道题直接没有思路 所以直接百度了别人AC的代码 发现是计算几何问题
先给大家补充一下知识吧 快速排斥实验 和 跨立实验
http://blog.sina.com.cn/s/blog_71dbfe2e0101f7zb.html
这里面介绍挺全面的 我也从里面学会了跨立实验 和快速排斥实验
快速排斥实验
关键代码:
min(a.x1,a.x2)<=max(b.x1,b.x2)&&
min(b.x1,b.x2)<=max(a.x1,a.x2)&&
min(a.y1,a.y2)<=max(b.y1,b.y2)&&
min(b.y1,b.y2)<=max(a.y1,a.y2)
通过了快速排斥实验之后还有一些特殊情况人需要判断 所以这里就需要通过跨立实验
跨立实验关键代码
((P3-P1)叉乘(P2-P1) )点乘 ((P4 - P1) 叉乘 (P2 - P1)) >=0才可以 由于只有当线段P3P4和P1P2跨立成功才可以认为相交
*/

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>

using namespace std;

typedef struct bian
{
    double x1,x2;
    double y1,y2;
    int father;
}node;

int rr[1007];
node t[1007];
int father(int a)
{
    while(a!=t[a].father)
        a = t[a].father;
    return a;
}
void Union_set(int a,int b)
{
    int pa = father(a);
    int pb = father(b);
    if(pa!=pb)
    {
        t[pa].father = pb;
        rr[pb] += rr[pa];
    }
}
int xiangjiao(node a,node b)
{
    if(min(a.x1,a.x2)<=max(b.x1,b.x2)&&min(b.x1,b.x2)<=max(a.x1,a.x2)&&min(a.y1,a.y2)<=max(b.y1,b.y2)&&min(b.y1,b.y2)<=max(a.y1,a.y2))
    {
        //跨立实验
        double t1 = (a.x2-a.x1)*(b.y1 - a.y1) - (b.x1 - a.x1 )*(a.y2 - a.y1);
        double t2 = (a.x2-a.x1)*(b.y2 - a.y1) - (b.x2 - a.x1 )*(a.y2 - a.y1);
        double t3 = (b.x2 - b.x1)*(a.y1 - b.y1) - (a.x1 - b.x1) *(b.y2 - b.y1);
        double t4 = (b.x2 - b.x1)*(a.y2 - b.y1) - (a.x2 - b.x1) *(b.y2 - b.y1);
        if(t1*t2<=0&&t3*t4<=0)
            return 1;
    }
    return 0;
}
int main()
{
    int ncase;
    cin>>ncase;
    while(ncase--)
    {
        int cmd;
        cin>>cmd;
        for(int i =1;i<=cmd;i++)
        {
            t[i].father = i;
            rr[i] = 1;
        }
        int sum = 1;
        while(cmd--)
        {
            string str;
            cin>>str;
            if(str[0]=='P')
            {
                cin>>t[sum].x1>>t[sum].y1>>t[sum].x2>>t[sum].y2;
                for(int i =1;i<sum;i++)
                {
                    if(xiangjiao(t[i],t[sum]))
                    {
                        Union_set(i,sum);
                    }
                }
                sum++;
            }else
            {
                int mm;
                cin>>mm;
                cout<<rr[father(mm)]<<endl;
            }
        }
        if(ncase)
            cout<<endl;

    }
    return 0;
}
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.Linq; namespace FixedOverkillPlugin { public class Commands { // 配置参数 public class OverkillOptions { public double Tolerance { get; set; } = 0.1; public bool IgnoreColor { get; set; } = true; public bool IgnoreLayer { get; set; } = true; public bool IgnoreLinetype { get; set; } = true; public bool OptimizePolylines { get; set; } = true; public bool MergeOverlapping { get; set; } = true; public bool MergeCollinear { get; set; } = true; public bool PreserveAssociativity { get; set; } = true; } [CommandMethod("MG", CommandFlags.Modal)] public void MergeLines() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { // 获取用户选项 OverkillOptions options = GetUserOptions(ed); if (options == null) return; // 获取选择集 PromptSelectionResult selResult = ed.GetSelection(); if (selResult.Status != PromptStatus.OK) return; using (Transaction tr = db.TransactionManager.StartTransaction()) { // 收集所有线段 var objectsToErase = new HashSet<ObjectId>(); var allSegments = new List<LineSegment>(); // 收集所有线段 CollectAllSegments(selResult, tr, options, allSegments, objectsToErase, ed); // 删除原始对象 DeleteOriginalObjects(tr, objectsToErase, ed); // 处理线段 BlockTableRecord btr = (BlockTableRecord)tr.GetObject( db.CurrentSpaceId, OpenMode.ForWrite); // 合并线段 List<Line> mergedLines = MergeSegments(allSegments, options, ed); // 添加新实体 foreach (Line newLine in mergedLines) { btr.AppendEntity(newLine); tr.AddNewlyCreatedDBObject(newLine, true); } tr.Commit(); } ed.WriteMessage(Environment.NewLine + "线段合并完成!"); } catch (System.Exception ex) { ed.WriteMessage(Environment.NewLine + $"错误: {ex.Message}" + Environment.NewLine + $"{ex.StackTrace}"); } } // 获取用户选项(修复了关键字设置问题) private OverkillOptions GetUserOptions(Editor ed) { OverkillOptions options = new OverkillOptions(); // 创建关键字选项 var kws = new List<Tuple<string, string, string>>(); kws.Add(Tuple.Create("Tolerance", "公差(T)", "公差(T)")); kws.Add(Tuple.Create("Ignore", "忽略特性(I)", "忽略特性(I)")); kws.Add(Tuple.Create("Optimize", "优化选项(O)", "优化选项(O)")); kws.Add(Tuple.Create("Accept", "接受", "接受")); while (true) { PromptKeywordOptions pko = new PromptKeywordOptions( Environment.NewLine + "设置选项 [公差(T)/忽略特性(I)/优化选项(O)/接受(A)]: "); // 添加关键字选项 foreach (var kw in kws) { pko.Keywords.Add(kw.Item1, kw.Item2, kw.Item3); } pko.AllowNone = true; PromptResult pr = ed.GetKeywords(pko); if (pr.Status != PromptStatus.OK) return null; switch (pr.StringResult) { case "Tolerance": PromptDoubleOptions pdo = new PromptDoubleOptions( Environment.NewLine + $"输入公差值 <{options.Tolerance}>: "); pdo.DefaultValue = options.Tolerance; pdo.AllowNegative = false; pdo.AllowZero = false; PromptDoubleResult pdr = ed.GetDouble(pdo); if (pdr.Status == PromptStatus.OK) { options.Tolerance = pdr.Value; } break; case "Ignore": var iko = new PromptKeywordOptions( Environment.NewLine + "选择忽略的特性 [颜色(C)/图层(LA)/线型(LT)/全部(A)/无(N)]: "); iko.Keywords.Add("Color", "颜色(C)", "颜色(C)"); iko.Keywords.Add("Layer", "图层(LA)", "图层(LA)"); iko.Keywords.Add("Linetype", "线型(LT)", "线型(LT)"); iko.Keywords.Add("All", "全部(A)", "全部(A)"); iko.Keywords.Add("None", "无(N)", "无(N)"); PromptResult ikr = ed.GetKeywords(iko); if (ikr.Status == PromptStatus.OK) { switch (ikr.StringResult) { case "Color": options.IgnoreColor = !options.IgnoreColor; break; case "Layer": options.IgnoreLayer = !options.IgnoreLayer; break; case "Linetype": options.IgnoreLinetype = !options.IgnoreLinetype; break; case "All": options.IgnoreColor = true; options.IgnoreLayer = true; options.IgnoreLinetype = true; break; case "None": options.IgnoreColor = false; options.IgnoreLayer = false; options.IgnoreLinetype = false; break; } } break; case "Optimize": var oko = new PromptKeywordOptions( Environment.NewLine + "选择优化选项 [优化多段线(P)/合并重叠(O)/合并共线(C)/保持关联(K)]: "); oko.Keywords.Add("Polyline", "优化多段线(P)", "优化多段线(P)"); oko.Keywords.Add("Overlap", "合并重叠(O)", "合并重叠(O)"); oko.Keywords.Add("Collinear", "合并共线(C)", "合并共线(C)"); oko.Keywords.Add("Associativity", "保持关联(K)", "保持关联(K)"); PromptResult okr = ed.GetKeywords(oko); if (okr.Status == PromptStatus.OK) { switch (okr.StringResult) { case "Polyline": options.OptimizePolylines = !options.OptimizePolylines; break; case "Overlap": options.MergeOverlapping = !options.MergeOverlapping; break; case "Collinear": options.MergeCollinear = !options.MergeCollinear; break; case "Associativity": options.PreserveAssociativity = !options.PreserveAssociativity; break; } } break; case "Accept": return options; } // 显示当前设置 ed.WriteMessage(Environment.NewLine + $"当前设置: 公差={options.Tolerance}, " + $"忽略特性[颜色={options.IgnoreColor}, 图层={options.IgnoreLayer}, 线型={options.IgnoreLinetype}], " + $"优化选项[多段线={options.OptimizePolylines}, 重叠={options.MergeOverlapping}, " + $"共线={options.MergeCollinear}, 关联={options.PreserveAssociativity}]"); } } // 线段表示类 public class LineSegment { public Point3d Start { get; set; } public Point3d End { get; set; } public ObjectId OriginalId { get; set; } = ObjectId.Null; public string Layer { get; set; } public string Linetype { get; set; } public int Color { get; set; } public bool IsPolylineSegment { get; set; } public LineSegment(Point3d start, Point3d end) { Start = start; End = end; } public Extents3d Extents => new Extents3d(Start, End); } // 收集所有线段 private void CollectAllSegments(PromptSelectionResult selResult, Transaction tr, OverkillOptions options, List<LineSegment> allSegments, HashSet<ObjectId> objectsToErase, Editor ed) { int totalObjects = selResult.Value.Count; int processed = 0; foreach (SelectedObject selObj in selResult.Value) { processed++; if (processed % 100 == 0) ed.WriteMessage(Environment.NewLine + $"已处理: {processed}/{totalObjects}"); Entity ent = tr.GetObject(selObj.ObjectId, OpenMode.ForRead) as Entity; if (ent == null) continue; // 记录要删除的对象 objectsToErase.Add(ent.ObjectId); // 处理直线 if (ent is Line line) { allSegments.Add(new LineSegment(line.StartPoint, line.EndPoint) { OriginalId = line.ObjectId, Layer = options.IgnoreLayer ? "" : line.Layer, Linetype = options.IgnoreLinetype ? "" : line.Linetype, Color = options.IgnoreColor ? 0 : line.ColorIndex }); } // 处理多段线 else if (ent is Polyline pline && options.OptimizePolylines) { for (int i = 0; i < pline.NumberOfVertices - 1; i++) { allSegments.Add(new LineSegment( pline.GetPoint3dAt(i), pline.GetPoint3dAt(i + 1) ) { OriginalId = pline.ObjectId, Layer = options.IgnoreLayer ? "" : pline.Layer, Linetype = options.IgnoreLinetype ? "" : pline.Linetype, Color = options.IgnoreColor ? 0 : pline.ColorIndex, IsPolylineSegment = true }); } } // 处理其他实体 else if (options.PreserveAssociativity) { objectsToErase.Remove(ent.ObjectId); } } } // 删除原始对象 private void DeleteOriginalObjects(Transaction tr, HashSet<ObjectId> objectsToErase, Editor ed) { int total = objectsToErase.Count; int processed = 0; int deletedCount = 0; foreach (ObjectId id in objectsToErase) { processed++; if (processed % 100 == 0) ed.WriteMessage(Environment.NewLine + $"删除对象: {processed}/{total}"); if (id.IsValid && !id.IsErased && id.IsResident) { try { DBObject obj = tr.GetObject(id, OpenMode.ForWrite); if (obj != null) { obj.Erase(); deletedCount++; } } catch { /* 忽略错误 */ } } } ed.WriteMessage(Environment.NewLine + $"成功删除 {deletedCount} 个对象"); } // 高级线段合并算法 private List<Line> MergeSegments(List<LineSegment> segments, OverkillOptions options, Editor ed) { if (segments.Count == 0) return new List<Line>(); ed.WriteMessage(Environment.NewLine + $"开始合并线段: {segments.Count} 条"); // 分组 var groupedSegments = segments .GroupBy(s => new { Layer = options.IgnoreLayer ? "" : s.Layer, Linetype = options.IgnoreLinetype ? "" : s.Linetype, Color = options.IgnoreColor ? 0 : s.Color }) .ToList(); List<Line> result = new List<Line>(); int groupCount = 0; foreach (var group in groupedSegments) { groupCount++; ed.WriteMessage(Environment.NewLine + $"处理组 {groupCount}/{groupedSegments.Count}: " + $"图层={group.Key.Layer}, 线型={group.Key.Linetype}, 颜色={group.Key.Color}"); // 步骤1:打断重叠线段 List<LineSegment> brokenSegments = options.MergeOverlapping ? BreakOverlappingSegments(group.ToList(), options.Tolerance, ed) : group.ToList(); // 步骤2:合并共线线段 List<LineSegment> mergedSegments = options.MergeCollinear ? MergeCollinearSegments(brokenSegments, options.Tolerance, ed) : brokenSegments; // 转换为Line对象 foreach (var seg in mergedSegments) { Line newLine = new Line(seg.Start, seg.End); newLine.Layer = group.Key.Layer; newLine.Linetype = group.Key.Linetype; newLine.ColorIndex = group.Key.Color; result.Add(newLine); } } ed.WriteMessage(Environment.NewLine + $"合并完成: 原始 {segments.Count} 条 → 合并 {result.Count} 条"); return result; } // 打断重叠线段 private List<LineSegment> BreakOverlappingSegments(List<LineSegment> segments, double tolerance, Editor ed) { if (segments.Count < 2) return segments; // 使用空间索引加速 SpatialIndex index = BuildSpatialIndex(segments, tolerance); List<LineSegment> result = new List<LineSegment>(); HashSet<LineSegment> processed = new HashSet<LineSegment>(); int total = segments.Count; int processedCount = 0; foreach (LineSegment seg in segments) { processedCount++; if (processedCount % 100 == 0) ed.WriteMessage(Environment.NewLine + $"打断重叠: {processedCount}/{total}"); if (processed.Contains(seg)) continue; List<LineSegment> currentSegments = new List<LineSegment> { seg }; bool modified; do { modified = false; List<LineSegment> nextSegments = new List<LineSegment>(); foreach (LineSegment current in currentSegments) { // 查找可能重叠的线段 var candidates = index.Search(current.Extents) .Where(s => !processed.Contains(s) && s != current) .ToList(); bool broken = false; foreach (var candidate in candidates) { if (AreSegmentsOverlapping(current, candidate, tolerance)) { List<LineSegment> newSegments = BreakOverlappingPair(current, candidate, tolerance); nextSegments.AddRange(newSegments); processed.Add(candidate); broken = true; break; } } if (!broken) { nextSegments.Add(current); } else { modified = true; } } currentSegments = nextSegments; } while (modified); result.AddRange(currentSegments); processed.Add(seg); } return result; } // 检查线段是否重叠 private bool AreSegmentsOverlapping(LineSegment seg1, LineSegment seg2, double tolerance) { // 创建带公差的线段 Line line1 = new Line(seg1.Start, seg1.End); Line line2 = new Line(seg2.Start, seg2.End); // 计算方向向量 Vector3d dir1 = seg1.End - seg1.Start; Vector3d dir2 = seg2.End - seg2.Start; // 检查是否平行 if (!dir1.IsParallelTo(dir2, new Tolerance(tolerance, tolerance))) return false; // 检查投影重叠 double min1 = Math.Min(0, dir1.Length); double max1 = Math.Max(0, dir1.Length); double min2 = Math.Min(0, dir2.Length); double max2 = Math.Max(0, dir2.Length); double proj1 = ProjectPointOnLine(seg2.Start, seg1.Start, dir1, tolerance); double proj2 = ProjectPointOnLine(seg2.End, seg1.Start, dir1, tolerance); double seg2Min = Math.Min(proj1, proj2); double seg2Max = Math.Max(proj1, proj2); // 检查重叠 return (min1 <= seg2Max + tolerance && max1 >= seg2Min - tolerance) || (seg2Min <= max1 + tolerance && seg2Max >= min1 - tolerance); } // 投影点到线段 private double ProjectPointOnLine(Point3d point, Point3d lineStart, Vector3d direction, double tolerance) { Vector3d v = point - lineStart; return v.DotProduct(direction) / direction.Length; } // 打断重叠线段对 private List<LineSegment> BreakOverlappingPair(LineSegment seg1, LineSegment seg2, double tolerance) { // 计算投影点 Vector3d dir = seg1.End - seg1.Start; double projStart = ProjectPointOnLine(seg2.Start, seg1.Start, dir, tolerance); double projEnd = ProjectPointOnLine(seg2.End, seg1.Start, dir, tolerance); // 计算实际点 Point3d p1 = seg1.Start + dir * (projStart / dir.Length); Point3d p2 = seg1.Start + dir * (projEnd / dir.Length); // 创建分割点 List<double> splitParams = new List<double>(); splitParams.Add(0); // 起点 splitParams.Add(dir.Length); // 终点 if (projStart > 0 && projStart < dir.Length) splitParams.Add(projStart); if (projEnd > 0 && projEnd < dir.Length) splitParams.Add(projEnd); splitParams.Sort(); // 创建新线段 List<LineSegment> result = new List<LineSegment>(); for (int i = 0; i < splitParams.Count - 1; i++) { double startParam = splitParams[i]; double endParam = splitParams[i + 1]; // 跳过太小的线段 if (endParam - startParam < tolerance) continue; Point3d startPt = seg1.Start + dir * (startParam / dir.Length); Point3d endPt = seg1.Start + dir * (endParam / dir.Length); result.Add(new LineSegment(startPt, endPt)); } return result; } // 合并共线线段 private List<LineSegment> MergeCollinearSegments(List<LineSegment> segments, double tolerance, Editor ed) { if (segments.Count == 0) return segments; // 按起点排序 List<LineSegment> sortedSegments = segments .OrderBy(s => s.Start.X) .ThenBy(s => s.Start.Y) .ThenBy(s => s.Start.Z) .ToList(); // 使用并查集合并 UnionFind uf = new UnionFind(sortedSegments.Count); // 构建空间索引 SpatialIndex index = BuildSpatialIndex(sortedSegments, tolerance); for (int i = 0; i < sortedSegments.Count; i++) { LineSegment seg1 = sortedSegments[i]; // 查找附近线段 var candidates = index.Search(seg1.Extents) .Where((s, idx) => idx > i) // 只检查后面的线段 .ToList(); foreach (var candidate in candidates) { int j = sortedSegments.IndexOf(candidate); if (j <= i) continue; if (AreSegmentsConnectable(seg1, candidate, tolerance)) { uf.Union(i, j); } } } // 分组合并 Dictionary<int, List<LineSegment>> groups = new Dictionary<int, List<LineSegment>>(); for (int i = 0; i < sortedSegments.Count; i++) { int root = uf.Find(i); if (!groups.ContainsKey(root)) groups[root] = new List<LineSegment>(); groups[root].Add(sortedSegments[i]); } // 合并每组线段 List<LineSegment> result = new List<LineSegment>(); foreach (var group in groups.Values) { if (group.Count == 1) { result.Add(group[0]); continue; } // 计算合并后的线段 Point3d minPoint = group[0].Start; Point3d maxPoint = group[0].End; foreach (var seg in group) { minPoint = PointMin(minPoint, PointMin(seg.Start, seg.End)); maxPoint = PointMax(maxPoint, PointMax(seg.Start, seg.End)); } result.Add(new LineSegment(minPoint, maxPoint)); } return result; } // 检查线段是否可连接 private bool AreSegmentsConnectable(LineSegment seg1, LineSegment seg2, double tolerance) { Vector3d dir1 = seg1.End - seg1.Start; Vector3d dir2 = seg2.End - seg2.Start; // 检查方向平行 if (!dir1.IsParallelTo(dir2, new Tolerance(tolerance, tolerance))) return false; // 检查端点连接 Tolerance tol = new Tolerance(tolerance, tolerance); return seg1.End.IsEqualTo(seg2.Start, tol) || seg1.Start.IsEqualTo(seg2.End, tol) || seg1.End.IsEqualTo(seg2.End, tol) || seg1.Start.IsEqualTo(seg2.Start, tol); } // 辅助方法:获取最小点 private Point3d PointMin(Point3d a, Point3d b) { return new Point3d( Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Min(a.Z, b.Z)); } // 辅助方法:获取最大点 private Point3d PointMax(Point3d a, Point3d b) { return new Point3d( Math.Max(a.X, b.X), Math.Max(a.Y, b.Y), Math.Max(a.Z, b.Z)); } // 构建空间索引 private SpatialIndex BuildSpatialIndex(List<LineSegment> segments, double tolerance) { SpatialIndex index = new SpatialIndex(); foreach (LineSegment seg in segments) { // 正确创建扩展后的边界框 Point3d min = seg.Extents.MinPoint; Point3d max = seg.Extents.MaxPoint; // 创建新的扩展边界框 Point3d newMin = new Point3d( min.X - tolerance, min.Y - tolerance, min.Z - tolerance); Point3d newMax = new Point3d( max.X + tolerance, max.Y + tolerance, max.Z + tolerance); // 使用新的Extents3d对象 Extents3d extendedExt = new Extents3d(newMin, newMax); index.Add(extendedExt, seg); } return index; } } // 空间索引实现 public class SpatialIndex { private List<Tuple<Extents3d, Commands.LineSegment>> _items = new List<Tuple<Extents3d, Commands.LineSegment>>(); public void Add(Extents3d extents, Commands.LineSegment segment) { _items.Add(new Tuple<Extents3d, Commands.LineSegment>(extents, segment)); } public IEnumerable<Commands.LineSegment> Search(Extents3d searchExtents) { return _items .Where(item => item.Item1.MinPoint.X <= searchExtents.MaxPoint.X && item.Item1.MaxPoint.X >= searchExtents.MinPoint.X && item.Item1.MinPoint.Y <= searchExtents.MaxPoint.Y && item.Item1.MaxPoint.Y >= searchExtents.MinPoint.Y) .Select(item => item.Item2); } } // 并查集实现 public class UnionFind { private int[] parent; private int[] rank; public UnionFind(int size) { parent = new int[size]; rank = new int[size]; for (int i = 0; i < size; i++) { parent[i] = i; rank[i] = 0; } } public int Find(int x) { if (parent[x] != x) { parent[x] = Find(parent[x]); } return parent[x]; } public void Union(int x, int y) { int rootX = Find(x); int rootY = Find(y); if (rootX == rootY) return; if (rank[rootX] < rank[rootY]) { parent[rootX] = rootY; } else if (rank[rootX] > rank[rootY]) { parent[rootY] = rootX; } else { parent[rootY] = rootX; rank[rootX]++; } } } } 命令: MG 设置选项 [公差(T)/忽略特性(I)/优化选项(O)/接受(A)] [公差(T)/忽略特性(I)/优化选项(O)/接受]: 命令: MG 设置选项 [公差(T)/忽略特性(I)/优化选项(O)/接受(A)] [公差(T)/忽略特性(I)/优化选项(O)/接受]: A 无效的选项关键字。 设置选项 [公差(T)/忽略特性(I)/优化选项(O)/接受(A)] [公差(T)/忽略特性(I)/优化选项(O)/接受]: T 无效的选项关键字。 设置选项 [公差(T)/忽略特性(I)/优化选项(O)/接受(A)] [公差(T)/忽略特性(I)/优化选项(O)/接受]: I 无效的选项关键字。
最新发布
07-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值