我的创作纪念日

机缘

提示:可以和大家分享最初成为创作者的初心

机缘

我最初成为创作者的初心来源于对编程的热爱和分享的渴望。作为一名计算机专业的学生,我参与过一些实际项目和竞赛,积累了不少经验,而每一次完成一个项目、解决一个难题时的成就感也促使我希望把这些经验分享出来。通过创作,我不仅能够记录日常学习和实战项目中的思考过程,还可以通过文章交流技术,帮助其他在编程道路上遇到类似问题的人。比如,在编写前端开发技巧、数据结构优化或者算法实现的文章时,我都会格外投入,因为这些不仅能提升自己的表达能力,也有助于加深对知识的理解。

收获

在创作的过程中,我收获了许多温暖的关注。比如,目前大约有240位粉丝在关注我的更新,每当看到他们的赞和评论,我都非常高兴。有一次,一篇介绍双向广度优先搜索的文章获得了309次点赞、7次评论和24407次阅读量。这些积极的反馈和互动让我更有动力去分享自己的学习心得,也让我认识到很多志同道合的编程爱好者。通过交流,我结识了不少在算法、数据分析和前端开发等领域的优秀同行,我们彼此学习,共同成长。


日常

如今,创作已经成了我生活的一部分。我发现,每当学习或完成新的编程任务时,都会产生一种强烈的想法,把这些过程和方法分享给更多人。在有限的时间和精力下,我会在每晚编程后,将其中的亮点和技巧记录下来,稍作整理后发布成文章。这样不仅提升了自己的表达和总结能力,还能时常回顾这些点滴,找到进步的方向。


成就

提示:你过去写得最好的一段代码是什么? 请用代码块贴出来

例如:

  1. 某个解题代码

    复制代码
    ​
    #include <string>       
    #include <iostream>    
    #include <cstdio>       
    #include <queue>        
    #include <vector>      
    #include <cstring>      // 包含 C 风格字符串处理
    #include <algorithm>    // 包含常用算法
     
    using namespace std;    // 使用标准命名空间
     
    const int maxn = 5e5 + 10; // 定义最大状态数量
    int vis[maxn]; // 定义正向搜索访问标记数组
    int vis2[maxn]; // 定义反向搜索访问标记数组
    char d[10] = { "udlr" }, d2[10] = { "durl" }; // 定义移动方向字符数组
    int dir[4] = { -3, 3, -1, 1 }; // 定义方向对应的索引变化量
    int ha[9] = { 40320, 5040, 720, 120, 24, 6, 2, 1, 1 }; // 阶乘预处理数组,用于计算哈希值
    string a, b = "123456780"; // 定义初始状态和目标状态字符串
     
    // 记录节点信息的结构体
    struct node {
        int num; // 当前节点编号
        char ch; // 从父节点到当前节点的移动方向
    } pre[maxn]; // 定义节点信息数组
     
    // 用于存储状态及其编号的结构体
    struct node2 {
        int num; // '0'所在的位置
        string s; // 状态字符串
    } e; // 定义初始状态结构体
     
    // 递归输出解法路径
    void show(int x) {
        if (pre[x].num == -1) // 如果是初始节点,返回
            return;
        show(pre[x].num); // 递归输出前一个节点
        printf("%c", pre[x].ch); // 输出当前节点的移动方向
    }
     
    // 计算状态的哈希值
    int getha(string s) {
        int sum = 0; // 初始化哈希值
        for (int i = 0; i < 9; i++) { // 遍历字符串
            int k = 0; // 逆序数计数
            for (int j = i + 1; j < 9; j++) { // 计算逆序数
                if (s[j] < s[i]) k++;
            }
            sum += k * ha[i]; // 计算哈希值
        }
        return sum; // 返回哈希值
    }
     
    // 广度优先搜索,包含双向搜索
    void bfs() {
        int q = getha(e.s); // 计算初始状态的哈希值
        queue<node2> q1; // 定义正向搜索队列
        queue<node2> q2; // 定义反向搜索队列
        vis[q] = 1; // 标记初始状态已访问
        node2 f, g; // 定义状态结构体
        f.s = b; // 设置目标状态
        f.num = 8; // 设置'0'的位置
        int p = getha(f.s); // 计算目标状态的哈希值
        int x, k; // 定义临时变量
        vis2[p] = 2; // 标记目标状态已访问
        pre[1].num = -1; // 初始化路径记录
        pre[2].num = -1; // 初始化路径记录
        int num = 2; // 设置状态编号初始值
        q1.push(e); // 初始状态入队
        q2.push(f); // 目标状态入队
        while (!q1.empty() && !q2.empty()) { // 如果两个队列都不为空
            f = q1.front(); // 取出正向搜索队列的队首元素
            q1.pop(); // 弹出队首元素
            p = getha(f.s); // 计算当前状态的哈希值
            if (vis2[p]) { // 如果反向搜索已访问
                show(vis[p]); // 输出正向路径
                k = vis2[p]; // 取出反向路径起点
                while (pre[k].num != -1) { // 输出反向路径
                    printf("%c", pre[k].ch); // 输出方向字符
                    k = pre[k].num; // 取下一个节点
                }
                printf("\n"); // 输出换行
                return; // 结束搜索
            }
            for (int i = 0; i < 4; i++) { // 遍历四个方向
                if (i == 0 && f.num < 3) continue; // 如果不能向上移动,跳过
                if (i == 1 && f.num > 5) continue; // 如果不能向下移动,跳过
                if (i == 2 && f.num % 3 == 0) continue; // 如果不能向左移动,跳过
                if (i == 3 && f.num % 3 == 2) continue; // 如果不能向右移动,跳过
                x = f.num + dir[i]; // 计算移动后的'0'位置
                g = f; // 复制当前状态
                swap(g.s[f.num], g.s[x]); // 交换'0'与目标位置
                q = getha(g.s); // 计算新状态的哈希值
                if (vis[q]) continue; // 如果新状态已访问,跳过
                vis[q] = ++num; // 标记新状态已访问,并记录编号
                g.num = x; // 更新'0'的位置
                pre[num].num = vis[p]; // 记录路径信息
                pre[num].ch = d[i]; // 记录移动方向
                q1.push(g); // 新状态入队
            }
            f = q2.front(); // 取出反向搜索队列的队首元素
            q2.pop(); // 弹出队首元素
            p = getha(f.s); // 计算当前状态的哈希值
            if (vis[p]) { // 如果正向搜索已访问
                show(vis[p]); // 输出正向路径
                k = vis2[p]; // 取出反向路径起点
                while (pre[k].num != -1) { // 输出反向路径
                    printf("%c", pre[k].ch); // 输出方向字符
                    k = pre[k].num; // 取下一个节点
                }
                printf("\n"); // 输出换行
                return; // 结束搜索
            }
            for (int i = 0; i < 4; i++) { // 遍历四个方向
                if (i == 0 && f.num < 3) continue; // 如果不能向上移动,跳过
                if (i == 1 && f.num > 5) continue; // 如果不能向下移动,跳过
                if (i == 2 && f.num % 3 == 0) continue; // 如果不能向左移动,跳过
                if (i == 3 && f.num % 3 == 2) continue; // 如果不能向右移动,跳过
                x = f.num + dir[i]; // 计算移动后的'0'位置
                g = f; // 复制当前状态
                swap(g.s[f.num], g.s[x]); // 交换'0'与目标位置
                q = getha(g.s); // 计算新状态的哈希值
                if (vis2[q]) continue; // 如果新状态已访问,跳过
                vis2[q] = ++num; // 标记新状态已访问,并记录编号
                g.num = x; // 更新'0'的位置
                pre[num].num = vis2[p]; // 记录路径信息
                pre[num].ch = d2[i]; // 记录移动方向
                q2.push(g); // 新状态入队
            }
        }
        printf("unsolvable\n"); // 如果队列为空,输出 unsolvable
    }
     
    int main() {
        while (getline(cin, a)) { // 读取输入行
            int n, k = 0; // 定义字符串长度和逆序数计数器
            n = a.size(); // 获取输入字符串长度
            e.s = ""; // 初始化状态字符串
            for (int i = 0, j = 0; i < n; i++) { // 遍历输入字符串
                if (a[i] != ' ') { // 如果不是空格
                    if (a[i] == 'x') { // 如果是'x'
                        e.num = j; // 记录'0'的位置
                        e.s += '0'; // 将'x'转换为'0'
                    } else {
                        e.s += a[i]; // 添加字符到状态字符串
                    }
                    j++; // 字符计数器加1
                }
            }
            for (int i = 0; i < 9; i++) { // 遍历状态字符串
                if (e.s[i] == '0') continue; // 如果是'0'跳过
                for (int j = 0; j < i; j++) { // 计算逆序数
                    if (e.s[j] == '0') continue; // 如果是'0'跳过
                    if (e.s[j] > e.s[i]) k++; // 如果前面的数比当前数大,逆序数加1
                }
            }
            memset(vis2, 0, sizeof(vis2)); // 重置反向访问标记数组
            memset(vis, 0, sizeof(vis)); // 重置正向访问标记数组
            if (k & 1) { // 如果逆序数为奇数
                printf("unsolvable\n"); // 输出 unsolvable
            } else {
                bfs(); // 否则进行广度优先搜索
            }
        }
        return 0; // 程序结束
    }
     
    ​

憧憬

在未来的职业规划中,我希望能进一步拓展在算法与数据结构方面的专业知识,并在某天成为技术社区中的一名受欢迎的创作者。

相关推荐
无己心2 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u0103055278 天前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u0103055278 天前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝9 天前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u01030552710 天前
Java图像处理实战指南
人工智能·1024程序员节
u01030552710 天前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u01030552712 天前
Java实用类应用精讲
人工智能·1024程序员节
u01030552713 天前
Java I/O核心操作实战
人工智能·1024程序员节
u01030552714 天前
ArrayList操作详解与实战应用
人工智能·1024程序员节
u01030552715 天前
Java模块化编程实战指南
人工智能·笔记·1024程序员节