彻头彻尾的理解回溯算法

KMP算法详解 --- 彻头彻尾理解KMP算法 前言     之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k。   但是问题在于如何求出这个最大前后缀长度呢?   我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,   后来翻看算法导论32章 字符串匹配,虽然讲到了对前后缀计算的正确性,但是大量的推理证明不大好理解,没有与程序结合起来讲。   今天我在这里讲一讲我的一些理解,希望大家多多 阅读详情

定义

在程序设计中,有相当一类求一组解,或求全部解或求最优解的问题,例如读者熟悉的八皇后问题,不是根据某种特定的计算法则,而是利用试探和回溯的搜索技术求解。回溯法也是设计递归过程的一种重要方法,它的求解过程实质上是一个先序遍历一棵"状态树"的过程,只是这棵树不是遍历前预先建立的,而是隐含在遍历过程中。

---《数据结构》(严蔚敏)

怎么理解这段话呢?

首先,某种问题的解我们很难去找规律计算出来,没有公式可循,只能列出所有可能的解,然后一个个检查每个解是否符合我们要找的条件,也就是通常说的遍历。而解空间很多是树型的,就是树的遍历。

其次,树的先序遍历,也就是根是先被检查的,二叉树的先序遍历是根,左子树,右子树的顺序被输出。如果把树看做一种特殊的图的话,DFS就是先序遍历。所以,回溯和DFS是联系非常紧密的,可以认为回溯是DFS的一种应用场景。另外,DFS有个好处,它只存储深度,不存储广度。所以空间复杂度较小,而时间复杂度较大。

最后,某些解空间是非常大的,可以认为是一个非常庞大的树,此时完全遍历的时间复杂度是难以忍受的。此时可以在遍历的同时检查一些条件,当遍历某分支的时候,若发现条件不满足,则退回到根节点进入下一个分支的遍历。这就是“回溯”这个词的来源。而根据条件有选择的遍历,叫做剪枝或分枝定界。

DFS

首先看DFS,下面是算法导论上DFS的伪代码,值得一行行的去品味。需要注意染色的过程,因为图有可能是有环的,所以需要记录那些节点被访问过了,那些没有,而树的遍历是没有染色过程的。而且它用 π[m]来记录m的父节点,也就可以记录DFS时的路径。

DFS(G)
1  for each vertex u ∈ V [G]
2       do color[u] ← WHITE
3          π[u] ← NIL
4  time ← 0
5  for each vertex u ∈ V [G]
6       do if color[u] = WHITE
7             then DFS-VISIT(u)
DFS-VISIT(u)
1  color[u] ← GRAY
2  time ← time +1
3  d[u] <-time
4  for each v ∈ Adj[u]
5       do if color[v] = WHITE
6             then π[v] ← u
7                        DFS-VISIT(v)
8  color[u] <-BLACK

例子

例一:求幂集问题,就是返回一个集合所有的子集。为什么叫幂集呢?因为一个集合有n个元素,那么它的所有的子集数是2^n个。比如[1,2,3]的子集是[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]。

也就是下面这棵树的叶子节点:


那问题就变成了如何输出一棵树的叶子节点。那就需要知道现在到底遍历到哪一层了。方法有很多,可以用全局变量记录,也可以用递归函数的参数记录。

A)这里是用全局变量记录,在进入函数的时候level++,退出函数的时候level--

int level=0;
vector<vector<int> > result;
vector<int> temp;
void dfs(vector<int>& S){
    level++;
    if(level>S.size()){
        result.push_back(temp);
        level--;
        return;
    }
    temp.push_back(S[level-1]);
    dfs(S);
    temp.pop_back();
    dfs(S);
    level--;
    return;
}
vector<vector<int> > subsets(vector<int>& S){
    sort(S.begin(),S.end());
    dfs(S);
    reverse(result.begin(),result.end());
    return result;
}

B)这里记录层数用的是函数参数

vector<vector<int> > result;
vector<int> temp;
void dfs(vector<int>& S, int i){
    if(i==S.size()){
        result.push_back(temp);
        return;
    }
    temp.push_back(S[i]);
    dfs(S,i+1);
    temp.pop_back();
    dfs(S,i+1);
    return;
}
vector<vector<int> > subsets(vector<int>& S){
    dfs(S,0);
    reverse(result.begin(),result.end());
    return result;
}

总结一下,伪代码就是:

void dfs(层数){

if(条件){

    输出;

}

else{

    左子树的处理;

    dfs(层数+1);

    右子树的处理;

    dfs(层数+1);

}

}

例二:皇后问题,比如8*8的棋盘,能摆放多少个皇后呢?国际象棋规则,皇后在同一行,同一列,同一斜线均可互相攻击。

伪代码如下:

int a[n];
void try(int i)
{
    if(i==n){
        输出结果;
         }
         else
         {
                   for(j = 下界; j <= 上界; j=j+1)  // 枚举i所有可能的路径
                   {
                            if(fun(j))                // 满足限界函数和约束条件
                            {
                                     a[i] = 1;
                                     ...                        // 其他操作
                                     try(i+1);
                                     a[j] = 0;
                            }
                   }
         }
 }

根据伪代码,写出最关键的一段代码如下。其中vector<vector<int> > m是全局变量,用来记录遍历轨迹,遍历前设上值,遍历后去掉。每一次调到output的时候,所有压入栈中的函数返回,都会调到m[level][i]=0;

void dfs(int level){  
    if(level==N){  
        output();  
    }  
    else{  
        for(int i=0;i<N;i++){  
            if(check(level+1,i+1)){  
                m[level][i]=1;  
                dfs(level+1);  
                m[level][i]=0;  
            }  
        }  
    }  
}  

完整代码:

int N;  
vector<vector<int> > m;  
vector<vector<string> > result;  
bool check(int row,int column){  
            if(row==1) return true;  
            int i,j;  
            for(i=0;i<=row-2;i++){  
                if(m[i][column-1]==1) return false;  
            }  
            i = row-2;  
            j = i-(row-column);  
            while(i>=0&&j>=0){  
                if(m[i][j]==1) return false;  
                i--;  
                j--;  
            }  
            i = row-2;  
            j = row+column-i-2;  
            while(i>=0&&j<=N-1){  
                if(m[i][j]==1) return false;  
                i--;  
                j++;  
            }  
            return true;  
        }  
void output()  
{  
    vector<string> vec;  
    for(int i=0;i<N;i++){  
        string s;  
        for(int j=0;j<N;j++){  
            if(m[i][j]==1)  
                s.push_back('Q');  
            else  
                s.push_back('.');  
        }  
        vec.push_back(s);  
    }  
    result.push_back(vec);  
}  
void dfs(int level){  
    if(level==N){  
        output();  
    }  
    else{  
        for(int i=0;i<N;i++){  
            if(check(level+1,i+1)){  
                m[level][i]=1;  
                dfs(level+1);  
                m[level][i]=0;  
            }  
        }  
    }  
}  
vector<vector<string> > solveNQueens(int n) {  
    N=n;  
    for(int i=0;i<n;i++){  
        vector<int> a(n,0);  
        m.push_back(a);  
    }  
    dfs(0);  
    return result;  
}

例三:数独问题,就是给出一个数独,解决它。

比如给出:


求解:


解空间是这样的:


由于数独都是9*9的,所以解空间有81层,每层有9个分支,我们做的就是遍历这个解空间。

如果只求一个解,那我们可以在得到解之后返回,而标记是否得到解可以用全局变量或返回值来做,

用全局变量的话,代码如下:

bool flag= false;
bool check(int k, vector<vector<char> > &board){
        int x=k/9;
        int y=k%9;
        for (int i = 0; i < 9; i++)
            if (i != x && board[i][y] == board[x][y])
                return false;
        for (int j = 0; j < 9; j++)
            if (j != y && board[x][j] == board[x][y])
                return false;
        for (int i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)
            for (int j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)
                if (i != x && j != y && board[i][j] == board[x][y])
                    return false;
        return true;
    }
void dfs(int num,vector<vector<char> > &board){
    if(num==81){
        flag=true;
        return;
    }
    else{
        int x=num/9;
        int y=num%9;
        if(board[x][y]=='.'){
            for(int i=1;i<=9;i++){
                board[x][y]=i+'0';
                if(check(num,board)){
                    dfs(num+1,board);
                    if(flag)
                        return;
                }
            }
            board[x][y]='.';
        }
        else{
            dfs(num+1,board);
        }
    }
}
void solveSudoku(vector<vector<char> > &board) {
    dfs(0,board);
}
用返回值的话,关键部分做一下修改就可以了:

 bool f(int i, vector<vector<char> > &board){
        if(i==n*m)
            return true;
        if(board[i/n][i%m]=='.'){
            for(int k=1;k<=9;k++){
                board[i/n][i%m]=k+'0';
                    if(check(i,board) && f(i+1,board))
                            return true;
            }
            board[i/n][i%m]='.';
            return false;
        }
        else
            return f(i+1,board);
    }

要求得到所有解的话,可以在解出现的时候存下来:

vector<vector<vector<char> >> sum;
bool check(int k, vector<vector<char> > &board){
        int x=k/9;
        int y=k%9;
        for (int i = 0; i < 9; i++)
            if (i != x && board[i][y] == board[x][y])
                return false;
        for (int j = 0; j < 9; j++)
            if (j != y && board[x][j] == board[x][y])
                return false;
        for (int i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)
            for (int j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)
                if (i != x && j != y && board[i][j] == board[x][y])
                    return false;
        return true;
    }
void dfs(int num,vector<vector<char> > &board){
    if(num==81){
        sum.push_back(board);
        return;
    }
    else{
        int x=num/9;
        int y=num%9;
        if(board[x][y]=='.'){
            for(int i=1;i<=9;i++){
                board[x][y]=i+'0';
                if(check(num,board)){
                    dfs(num+1,board);
                    //if(flag)
                      //  return;
                }
            }
            board[x][y]='.';
        }
        else{
            dfs(num+1,board);
        }
    }
}
void solveSudoku(vector<vector<char> > &board) {
    dfs(0,board);
}
int main()
{
    vector<string> myboard({"...748...","7........",".2.1.9...","..7...24.",".64.1.59.",".98...3..","...8.3.2.","........6","...2759.."});
    vector<char> temp(9,'.');
    vector<vector<char> > board(9,temp);
    for(int i=0;i<myboard.size();i++){
        for(int j=0;j<myboard[i].length();j++){
            board[i][j]=myboard[i][j];
        }
    }
    solveSudoku(board);
    for(int k=0;k<sum.size();k++){
    for(int i=0;i<sum[k].size();i++){
        for(int j=0;j<sum[k][i].size();j++){
            cout<<sum[k][i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<"######"<<endl;
    }
    cout<<"sum is "<<sum.size()<<endl;
    cout << "Hello world!" << endl;
    return 0;
}

最终,我们得到了8个解。

wiki上有一张图片形象的表达了这个回溯的过程:



智能车竞赛新手入门:从硬件搭建到PID控制算法全解析 嵌入式系统开发是连接软件与硬件的核心技术,其核心在于通过微控制器(如单片机)实现对物理设备的实时感知与控制。其工作原理涉及传感器数据采集、信号处理、控制算法决策与执行器驱动等多个环节。这项技术的核心价值在于能将抽象算法转化为具体的物理运动,是机器人、自动驾驶等领域的工程实践基础。在诸如全国大学生智能车竞赛这类典型应用场景中,参赛者需要综合运用图像处理、PID控制等算法,让模型车在赛道上实现自主循迹竞速。本文以新手视角,深入剖析了从车模机械调整、电路设计到摄像头图像处理和PID参数整定等完整流程,其中重点探讨 阅读详情

相关推荐

NoC片上网络:从总线瓶颈到多核互连的设计关键与未来演进

随着多核处理器与AI加速器规模不断扩张,传统共享总线在带宽、时序和功耗上的瓶颈日益凸显,片上网络(NoC)因此成为取代总线的新一代片内互连方案。NoC借鉴计算机网络的分组交换思想,通过路由器、网络接口和物理链路将CPU核、缓存和内存控制器连接起来,将通信局部化,从而突破可扩展性限制。其设计核心涉及拓扑结构、路由算法、流控机制等关键决策,直接影响多核芯片的延迟、吞吐与功耗。NoC不仅应用于CPU和GPU互连,更是AI大模型训练、Chiplet芯粒封装等前沿技术的基础支撑。本文围绕NoC的兴起原因、设计三要素、

weixin_34414650的博客 406

回溯算法——好的开始

学习回溯算法的一个好的开始,避坑不走弯路

EGXXM的博客 380

蒙特卡洛强化学习:无模型、基于完整回合的价值估计

蒙特卡洛(Monte Carlo)方法是强化学习中一类核心的无模型(Model-Free)算法,其基本原理是利用智能体与环境交互产生的完整回合(Episode)轨迹,通过事后结算实际总回报(Return)来估计状态或状态-动作对的价值函数。它不依赖环境转移概率或奖励函数的先验知识,仅依靠大数定律实现无偏估计,天然适配高不确定性、难建模场景。相比动态规划需完整环境模型、时序差分需一步预测,MC以简洁性重建RL直觉,成为理解Q-learning、TD误差和深度RL(如REINFORCE)的基石。本文深入解析其E

weixin_33994429的博客 387

数据结构(六)—— 二叉树(4)回溯

回溯

weixin_42690036的博客 1459

3D高斯泼溅驱动的具身导航训练方法

具身导航是让AI智能体在三维环境中理解空间、规划路径并执行动作的核心能力。其技术基础依赖于高保真、实时、可微分的3D场景表征——传统NeRF因渲染慢、不可微而难以支撑在线策略优化,而3D Gaussian Splatting(3DGS)以显式点云+高斯椭球建模,实现照片级重建与毫秒级渲染,天然适配强化学习中的世界模型需求。该技术显著降低仿真-现实鸿沟,使低成本手机图像即可构建光学一致的视觉沙盒,支撑策略网络在逼真光影、遮挡与几何约束下完成端到端训练。典型应用场景包括高校机器人算法验证、轻量级具身AI开发及S

weixin_33824363的博客 559

AI代理运行时基础设施:从会话状态管理到生产级沙箱

AI代理运行时(Agent Runtime)是支撑大模型智能体稳定、安全、可审计执行的底层基础设施,其核心在于解耦模型推理与状态管理。通过将‘会话’建模为持久化事件日志(Event Log),而非依赖有限的上下文窗口,系统可实现故障可回放、行为可追溯、扩展无状态。该架构显著降低首token延迟、杜绝静默幻觉,并天然支持合规审计与SRE运维。典型技术价值体现在生产环境中的会话持久化、凭证零信任分发、工具沙箱按需销毁等能力,广泛应用于金融客服、代码诊断、销售自动化等高可靠性场景。

weixin_30522095的博客 366

二叉树--递归和回溯

设计一个递归函数,该函数的作用是计算包含当前节点的最大路径和。

MADAO的博客 246

葵花(Himawari)8/9卫星数据处理

李国春 葵花8(含葵花9,下同)是静止气象卫星,数据范围是星下点为140°E赤道上空的大圆盘。空间分辨率有500m、1km和2km三种。虽然其空间分辨率不高,但是有极高的时间分辨率,观测数据刷新仅10分钟。这对一些生态、农业和大范围自然灾害的动态检测具有非常高的应用价值。本文介绍如何使用RSD处理葵花8数据。

副组长的博客 1万+

1022. 从根到叶的二进制数之和

package com.heu.wsq.leetcode.tree; /** * 1022. 从根到叶的二进制数之和 * @author wsq * @date 2020/12/22 * 给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。 * 对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字

Codeoh的博客 281

第1关:STL模板之queue实例一:最少个数

头歌自创答案

xiyunSacire的博客 819

Simulink仿真状态空间中状态变量时域响应

起因 今天老师留了一道关于状态空间变量响应的题,于是想用simulink仿真,一开始使用state-space模块,但是发现它只能输出y,没办法显示状态变量的变化情况。然而状态变量之间的关系都可以表示为一阶微分方程组,因此我们考虑在Simulink中搭建微分方程组来求解这个问题。 微分方程组 x1˙=x2x2˙=−4x1−5x2+1(1)\dot{x_1}=x_2\\ \dot{x_2}=-4x_...

ZYunfei的博客 7454

二叉树搜索序列(回溯)

回溯算法

少渊的博客 1292

时间加强控制图,累计和控制图详细介绍,公式,计算 UCL,LCL,CL, sigma,C#实现

\(k\):参考值(通常取为检测偏移量的一半,例如 \(k = \frac{\delta \sigma}{2}\),\(\delta\)是希望检测的偏移量,\(\sigma\)是过程标准差)。- 示例中假设目标均值 \(\mu_0 = 10.0\),标准差 \(\sigma = 0.5\),参考值 \(k = 0.25\)(检测1σ偏移),控制限常数 \(h = 4\)。例如,若希望检测1个标准差的偏移(\(\delta = 1\)),则 \(k = 0.5\sigma\)。

专注于前沿技术的探索与实践,热衷于从代码逻辑、架构设计到行业应用等多维度深挖技术本质。期待在技术之路上与你共同成长~ 818

彻头彻尾的理解kmp

作者:July 时间:最初写于2011年12月,2014年7月21日晚10点 全部删除重写成此文,随后的半个多月不断反复改进。 1. 引言 本KMP原文最初写于2年多前的2011年12月,因当时初次接触KMP,思路混乱导致写也写得混乱。所以一直想找机会重新写下KMP,但苦于一直以来对KMP的理解始终不够,故才迟迟没有修改本文。 然近期因开了个算法班,班上专门讲解数据结...

I_O_fly的博客 549

[PCIe5.0] 2.2.7.1 TPH Rules

TPH 机制通过硬件提示优化数据流,适用于高性能计算和存储场景。

系统固件工程师 350

冷门但实用:Python爬取微信公众号历史文章,突破微信反爬限制(2025有效)

2025年微信公众号爬取的核心是「冷门方法+指纹伪装」,而非常规接口破解,itchat-uos+Playwright组合是突破设备指纹的关键;登录态持久化、动态Token实时获取、频率严格控制是避免被封禁的三大核心;文章内容解析需解决2025新增的编码混淆问题,chardet+BeautifulSoup是冷门但有效的方案;合规是前提,爬取频率、数据用途需严格遵守平台/法律规则。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 3780

Python 深拷贝与浅拷贝:数据复制的奥秘及回溯算法中的应用

在 Python 编程领域,数据复制是极为常见的操作。而深拷贝和浅拷贝这两个概念,如同紧密关联却又各具特色的双子星,在数据处理过程中扮演着重要角色。深入理解它们,不仅有助于编写出高效、准确的代码,还能避免许多因数据复制不当而引发的问题。本文将借助形象的比喻、丰富的代码示例,深入剖析深拷贝和浅拷贝的区别,并探讨它们在回溯算法中的具体应用。

进一步有进一步的欢喜~ 1100

手把手教你写上位机软件(c#、winform)

上位机软件模板

qq_34059233的博客 7万+

GEE:哨兵时间序列遥感数据和动态阈值方法计算物候时期EOS/SOS(2)

本文将分享和解释论文《Improved Estimates of Arctic Land Surface Phenology Using Sentinel-2 Time Series》中使用到的基于阈值估算北极地区的植被物候,特别是北极地区的植被季节开始和结束的日期(SoS和EoS)的方法和代码。该方法使用的是使用哨兵2数据,并实现了两种阈值方法( 无平滑的阈值方法、平滑后的阈值方法)。

养乐多的博客 2971

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

微积分、贪心算法与回溯:一个程序员眼中的 AI 深度思考本质

AI深度思考的本质解析:知识是高维碎片关联(微积分式逼近),早期模型因贪心算法陷入局部最优,新一代AI通过回溯机制修正路径。这揭示AI并非拥有意识,而是用数学暴力在知识迷宫中测量真理——所有拼图碎片本就来自人类认知本身。

smzx_boy2012的专栏 682

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

深度学习可理解性:工业级AI模型的三层可解释工程实践

深度学习可理解性是保障AI在医疗、制造、金融等高风险场景落地的核心能力,其本质是将黑箱决策转化为可追溯、可探查、可归因的工程事实。它源于对模型输入偏差、特征语义漂移和输出逻辑断裂的系统性防控,技术价值在于建立人机协同的信任契约——既避免‘能跑通却不敢用’的交付陷阱,也支撑合规审计与快速故障定位。典型应用场景包括CT影像辅助诊断中的病灶归因、工业缺陷检测的物理机制对齐、以及边缘设备上的轻量化决策日志生成。本文聚焦Towards AI与Medium社区高频讨论的实战痛点,拆解覆盖全生命周期的三层结构与DPT-L

366

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

代码,敲开新世界的大门

我是东北某不知名211的一名大一学生,在计算机这一块我可以说是一个彻头彻尾的小白、入门者。我学习的专业是计算机科学与技术(CS)。在录取结果出来的时候我才去开始认识这个专业,虽然如此但这丝毫不影响我对计算机的热情。他似乎对我有着独特的吸引力。于是我早早地开始在大学之前的暑假开始学习编程,很快陷入其中,我现在还不能忘记第一次完成一个小程序的时候那种成就感,这种感觉驱使着我不断地前进。在进入大学之后,凭借着暑假的自学,我学的非常轻松。偶然的一次看到了国内一些互联网公司的招聘条件,我发现上面的东西我所知甚少,我开

十八岁讨厌编程的博客 551

遗传算法实战:Python实现N皇后问题求解

遗传算法是一种受生物进化启发的通用随机优化方法,其核心在于通过选择、交叉与变异在解空间中迭代搜索最优解。相比传统穷举或回溯,它特别适用于大规模组合优化问题,如N皇后这类约束复杂、解空间呈阶乘级增长的任务。技术价值体现在可扩展编码设计、适应度函数对进化方向的精准引导,以及向量化实现带来的性能跃升。典型应用场景包括排班调度、芯片布线、电商商品组合优化等离散决策问题。本文以N皇后为载体,深入剖析基于NumPy的Python工程实现细节,涵盖种群初始化、冲突检测加速、fitness函数调参及早停机制设计等关键实践。

413

KNN算法原理与实战:从距离度量到可解释性建模

KNN(K近邻)是一种基于实例的监督学习算法,其核心在于利用特征空间中的距离度量来识别相似样本。它不依赖参数拟合,而是通过邻居投票(分类)或加权平均(回归)完成预测,天然具备强可解释性与低实现门槛。该方法对特征尺度敏感,需标准化/归一化预处理;K值选择直接影响偏差-方差权衡,须借助交叉验证调优;距离函数(如欧氏距离、余弦相似度)和邻居搜索策略(KD树、Ball树)共同决定模型效率与鲁棒性。广泛应用于推荐系统、异常检测、小样本分类等需透明决策的工程场景。

weixin_33851429的博客 627

8款在线3D建模工具全解析:从零基础到专业设计的云端工作流

3D建模是将三维构想数字化的核心技术,其原理是通过计算机图形学算法在虚拟空间中构建、编辑和渲染三维模型。这项技术的价值在于极大地降低了创意可视化和产品原型设计的门槛,广泛应用于工业设计、建筑设计、影视动画、游戏开发和3D打印等领域。随着云计算和WebGL技术的发展,3D建模工具正经历从本地软件到云端平台的范式转移,这解决了传统软件对硬件要求高、协作困难等痛点。本文聚焦于在线3D建模这一高效解决方案,深入剖析了包括Tinkercad、SketchUp Free、Onshape和Vectary在内的多款工具,它

weixin_30859423的博客 416
上一篇: Leetcode---N-Queens II
下一篇: Leetcode---Surrounded Regions
我把葡萄酿成酒
博客等级 码龄12年 275粉丝 198原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值