你好,
程序世界

第一行代码不是终点。
它是你开始独立解决问题的入口。

$ gcc hello.c -o hello
$ ./hello
Hello, world!
$
2026 新生衔接课 江启翔 · 软件工程 · 2024级

大多数人,本来就从“不懂”开始

17.6%

大致了解 Git 与 GitHub
30 / 170 人

了解 OJ
4.7%
了解 Git/GitHub
17.6%

“我还不会”不是劣势,
只是你的起点坐标。

今晚只做三件事:理解、动手、提问

00—20 MIN

认识程序、工具、报错与 OJ

20—45 MIN

跑通主演示题,看到数学如何压缩代码

45—70 MIN

前缀和优化+问卷高频答疑

70—90 MIN

现场提问+互动/备用题

如果某个问题现场更重要,我们就把时间让给它。课件不是铁轨,是地图。

先拆掉三个“劝退型”误解

01

“数学不好就不能编程”

很多入门程序先训练的是拆步骤、验证结果和表达逻辑。

02

“看懂代码等于会写”

真正的掌握标准是:合上答案,能独立写出并验证。

03

“报错说明我不适合”

报错不是人格鉴定,它只是程序给你的定位信息。

编译器通常不是在嘲讽你,虽然它的语气确实很像。

程序不是魔法:它是一个可重复的解决过程

输入 Input 程序接收到什么?数字、文字、文件、传感器数据……
处理 Process 按照明确规则计算、判断、循环与组织数据。
输出 Output 把结果交给人、文件、屏幕或另一个程序。
?

写代码之前先问:输入是什么?输出是什么?中间规则是什么?

第一段 C 程序,只做一件事:把话说出来

hello.c
#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}
01

引入工具:让程序知道 printf 从哪里来。

02

进入 main:程序从这里开始执行。

03

输出文字:括号、引号、分号都属于语法。

04

正常结束:返回 0 表示程序顺利完成。

三种语言不是三座孤岛,核心思维会迁移

C

更接近底层

语法严格、内存更显式。适合理解程序如何真正运行。

C++

能力更丰富

兼容大量 C 思维,同时提供类、模板与标准库等工具。

PYTHON

表达更简洁

语法负担较轻,适合快速验证想法、数据处理与 AI 实践。

语言会换,输入—处理—输出、分解、测试和调试不会消失。

入门阶段,先抓住这五块积木

01变量给数据起名字
02类型数据按什么规则存
03条件何时走哪条路
04循环重复做一件事
05函数把步骤封装复用

先会组合积木,再讨论宏伟城堡。别在“Hello World”阶段焦虑微服务。

“写代码”其实是一条工具链

编辑器VS Code:写与修改源代码
编译器把 C 代码翻译为可执行程序
终端运行命令、输入数据、观察输出
OJ用隐藏数据验证正确性与效率

文件:hello.c 是源代码;编译后得到可执行文件。

目录:终端当前所在位置,会影响程序能否找到文件。

同样是“跑不了”,原因可能完全不同

COMPILE ERROR

编译错误

语法或类型不合法,程序还没真正开始运行。

expected ';'

RUNTIME ERROR

运行错误

程序启动了,但访问非法内存、除零或发生异常。

segmentation fault

LOGIC ERROR

逻辑错误

程序能跑,甚至不报红字,但答案不符合需求。

expected 12, got 10

学生像侦探一样追踪代码错误

调试不是水平差的补救,
它就是正常开发过程

稳定复现 → 缩小范围 → 检查变量 → 修改一处 → 重新测试

红字很多时,先读第一条有意义的错误

compiler output
main.c:6:5: error:
expected ';' before 'return'

    printf("hello\n")
                       ^
    return 0;

更多错误可能只是连锁反应……
01

看文件名与行号:问题大概在哪里?

02

提取关键词:expected ';'

03

检查这一行和上一行,不要整段删除重写。

04

修复后重新编译,确认后续错误是否一起消失。

程序穿过隐藏测试门并通过评测

OJ:把你的程序送进隐藏测试关卡

题目规定输入、输出、数据范围和资源限制;提交后,系统自动验证。

提交之后,先学会读懂这六个信号

ACAccepted|答案通过
WAWrong Answer|答案错误
TLETime Limit Exceeded|超时
MLEMemory Limit Exceeded|超内存
RERuntime Error|运行错误
CECompile Error|编译错误

别把 WA 当成“我不行”;把它翻译成:至少还有一个情况没考虑到。

一定要做 OJ;也要知道,OJ 不是全部

OJ 主要训练
  • 问题分析与算法思维
  • 输入输出与边界处理
  • 时间 / 空间复杂度意识
  • 实现准确度
项目还要训练
  • 理解用户与需求
  • 文件、接口与版本控制
  • 测试、文档与协作
  • 长期维护与演示

真正有效的学习:
输入 → 修改 → 验证 → 复述

“看懂了”只是输入;能不看答案写出、改动并解释,才开始变成你的能力。

最低动作:亲手输入一次,再主动改一个条件或输入,观察结果。

看概念 / 示例
亲手输入
改动并测试
合上答案重写
掌握
不是眼熟

不要上来就敲代码,先让思路起床

01 输入我会得到什么数据?
02 输出最终必须给出什么?
03 约束范围决定类型与效率。
04 小例子手算一个可验证答案。
05 步骤把过程写成人话。
先写:“我准备怎样解决” 再写:“C 语言怎样表达”

样例通过,只说明样例通过

对程序结果
保持一点礼貌的怀疑

不要用“看起来应该没问题”当证据。

0

零 / 空

程序是否允许?

MIN

最小值

边界是否漏掉?

MAX

最大值

会不会溢出/超时?

负数

符号是否正确?

==

重复值

比较是否稳定?

1

最小规模

循环能否进入?

想拿高分,不能只练“提交代码”这一种动作

课堂基础

概念与语法

跟紧任课教师、PPT、作业与当期考核要求。

上机与 OJ

独立实现

自己写、编译、调试,处理隐藏数据与边界。

笔试与手写

阅读分析

没有 IDE 提示时,也能判断输出、改错与写函数。

往年资料用于辅助复习;当前要求,以2026级培养方案和任课教师通知为准。

先看你们真实会遇到的课程节奏

信息学院软件工程系2026—2027学年开课计划表
点击图片可全屏查看

课表来源:学院开课计划截图;后续如有调整,以学院正式通知和实际排课为准。

Python 在前C/C++ 在后:不是推倒重来

第一学期

Python 程序设计|3 / 2+2

课表中Python程序设计所在行
第二学期

C/C++ 程序设计|3 / 2+2

课表中C/C++程序设计所在行

现在,把一道题从人话翻译成数学,再翻译成代码。

顺序固定:题目 → 思路 → 公式 / 结论 → 代码。先别让代码抢镜。

01

题目先问什么?别急着猜代码

简化后的问题模型

n 个人围成一圈;每个人都说:

“我后面的两个人中,恰好一个说真话。”

求所有合法真假安排中,说谎人数的总和

INPUT

多组数据;每组给出人数 n。

OUTPUT

每组输出所有合法情况中的说谎人数总和。

CONSTRAINT

n 可到 1018,不能模拟每个人或枚举所有情况。

只要知道连续两个人,后面的状态就被锁定

0
1
1
0
1
1
周期 3
0 → 1 → 1 → 0 …
起点 00

000000…

所有人都说谎

起点 01

011011…

每 3 人重复一次

起点 10 / 11

101101… / 110110…

同一周期的另外两种平移

“一真一假”刚好可以写成异或 XOR

xi = xi+1 ⊕ xi+2
x = 1

这个人说真话

x = 0

这个人说假话

a ⊕ b = 1

a、b 恰好一个为真

数学模型不是为了显得高级,而是为了把长故事压缩成可推导的规则。

周期能否首尾相接,只看 n 是否是 3 的倍数

n % 3 ≠ 0

只有全假

答案 = n
OR
n % 3 = 0

四种安排

n + 3 × (n / 3) = 2n

最后的代码很短,不是因为题目没思考,而是因为思考已经替代码做完了。

三种语言,核心判断完全一样

点击标签切换
#include <stdio.h>

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        long long n;
        scanf("%lld", &n);

        // 周期 3 能闭合:全假贡献 n,三种周期排列共贡献 n
        if (n % 3 == 0) {
            printf("%lld\n", 2 * n);
        } else {
            // 周期无法闭合,只剩“所有人都说谎”
            printf("%lld\n", n);
        }
    }
    return 0;
}
#include <iostream>
using namespace std;

int main() {
    int t;
    cin >> t;
    while (t--) {
        long long n;
        cin >> n;

        // 数学结论不因语言改变
        if (n % 3 == 0) {
            cout << 2 * n << endl;
        } else {
            cout << n << endl;
        }
    }
    return 0;
}
t = int(input())
while t:
    t -= 1
    n = int(input())

    # 只有当 n 是 3 的倍数,周期排列才能首尾相接
    if n % 3 == 0:
        print(2 * n)
    else:
        print(n)

给出 n 个数,计算所有不同下标数对的乘积和

S = Σ1 ≤ i < j ≤ n aiaj
INPUT

n 与 a1 … an

PAIR RULE

只取 i < j,每对恰好一次

LIMIT

n ≤ 2×105,暴力会超时

这道题最适合看“一个正确思路,怎样继续变成一个足够快的思路”。

两层循环没有错,错的是数据规模不允许

brute_force.c
long long s = 0;
for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
        s += a[i] * a[j];
    }
}
数对数量

n(n−1) / 2

n = 200,000

≈ 2×1010

不是“再优化一点点”能救的规模。

固定 ai 后,右边不必一个个乘:先整体求和

a₁固定
a₂右侧
a₃右侧
a₄右侧
右侧
aₙ右侧
ai(ai+1 + … + an)

真正重复的,不是乘法本身,而是每次都在重新计算“右边所有数的和”。

前缀和:提前保存“到这里为止的总和”

定义
sum[i] = a₁ + a₂ + … + aᵢ
A全部元素之和:sum[n]
B左侧到 aᵢ:sum[i]
A−B右侧之和:sum[n] − sum[i]
每个 i 的贡献
aᵢ × (sum[n] − sum[i])

每个位置只处理一次

时间复杂度从 O(n²) 降为 O(n)

代码只保留两件事:建前缀和,累加贡献

C / C++ / Python
#include <stdio.h>
long long a[200005], sum[200005];

int main() {
    long long n;
    scanf("%lld", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
        // sum[i]:前 i 个数之和
        sum[i] = sum[i - 1] + a[i];
    }

    long long s = 0;
    for (int i = 1; i <= n - 1; i++) {
        // a[i] 与右边所有数的乘积和
        s += a[i] * (sum[n] - sum[i]);
    }
    printf("%lld\n", s);
    return 0;
}
#include <iostream>
using namespace std;
long long a[200005], sum[200005];

int main() {
    long long n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        sum[i] = sum[i - 1] + a[i]; // 前缀和
    }

    long long s = 0;
    for (int i = 1; i <= n - 1; i++) {
        s += a[i] * (sum[n] - sum[i]); // 右侧之和
    }
    cout << s << endl;
    return 0;
}
n = int(input())
a = [0] + list(map(int, input().split()))
prefix = [0] * (n + 1)

for i in range(1, n + 1):
    # prefix[i] 表示前 i 个数之和
    prefix[i] = prefix[i - 1] + a[i]

answer = 0
for i in range(1, n):
    # 固定 a[i],一次得到它与右边所有数的乘积和
    answer += a[i] * (prefix[n] - prefix[i])

print(answer)

先把你现在的卡点说出来

环境配置 课程学习 OJ / 竞赛 AI / 项目

提问不需要先组织成论文摘要。先说你做了什么、哪里不符合预期。

学生与AI编码助手协作检查项目

AI 可以帮你加速;
最终验收人仍然是你

能运行 ≠ 正确;回答很自信 ≠ 有证据。

把 AI 用在反馈,不要用它替你完成学习

应该会
  • 解释报错与陌生概念
  • 生成边界测试样例
  • 比较两种思路的差异
  • 帮助缩小问题范围
  • 运行、修改、验证并复述
/
不能做
  • 提交自己无法解释的代码
  • 把作业、考试全部交给 AI
  • 上传密码、Token 与未公开代码
  • 因为语气肯定就默认正确
  • 绕开课程的学术诚信要求

暑假工具清单,按阶段解锁就好

NOW / 实际使用

VS Code
Python
一个 AI 对话工具

NEXT / 逐渐掌握

终端
Git
GitHub

WITH A PROJECT

Node.js
依赖管理
多人协作

KNOW IT EXISTS

Codex / Claude Code
AI Agent
Skill / Harness

Agent 能读取项目、修改文件和执行命令;Skill 是可复用的任务说明与工作流程。先理解,再上手。

Git 记录“发生了什么”,GitHub 让项目被保存与协作

Repository项目+版本历史
Commit一次有说明的版本记录
README项目说明与运行方法
Issue / PR记录问题并协作修改
$ git init  # 创建仓库
$ git add .  # 选择要记录的修改
$ git commit -m "完成第一个C程序" # 保存一个版本

新生第一步:创建仓库 → 保存代码 → 提交一次修改 → 写清楚 README。

学生面对项目、竞赛、科研和开源四条成长路径

项目、竞赛、科研、开源:是不同训练场,不是四项必修打卡

这些是探索窗口,不是统一进度条

大一上

跟紧课程、坚持 OJ;可以关注大创申报。

大一寒假

做一个小工具;尝试入门级竞赛。

大一下结束

兴趣更明确时,可以主动了解实验室与课题组。

暑假 / 项目期

逐步使用 Git/GitHub、AI Agent 与工程工具。

没申大创 ≠ 落后;没打比赛 ≠ 重开;没进组 ≠ 大学寄了。

资源少而精,比收藏夹爆仓更有用

微积分 I-1

平时慢学:宋浩、孔祥仁、梨米特
期中期末:一高数

线性代数 A

平时慢学:宋浩、梨米特
期中期末:框框老师、一高数

Python 程序设计

先看任课教师 PPT;看不懂就带着具体问题问 AI。网课不一定与课程完全对齐。

OJ 入门

洛谷入门题单  力扣  牛客

先跟课程做基础题,不需要大一开局硬刚困难题。

学长学姐的资料库,适合按需查阅

GITHUB REPOSITORY

XMU_SeLearning

打开仓库 ↗

适合预习、查漏补缺、寻找复习材料。

!

主要基于 2021 级软件工程课程资料。

仓库体积很大,维护者也建议按需下载。

不是 2026 级官方培养方案,也不是标准答案。

计算机专业,远不止“会不会刷题”

程序设计只是入口。之后你会遇到系统、网络、数据、软件工程、人工智能、安全、人机交互等不同世界。

不喜欢某一条路线,不等于不适合计算机。

计算机
COMPUTING
程序设计数据结构与算法操作系统 计算机网络数据库软件工程 人工智能网络安全人机交互体系结构

如果时间允许,挑战一只数学转化 Boss

P10415:最大公约数、最小质因数,怎样连接到“切最多正方形”。

02

把 W×H 的矩形切成尽可能多个相同正方形

QUESTION

正方形边长 d,必须满足什么?

d | W 且 d | H 且 d ≥ 2

也就是说,d 必须是 W 与 H 的公共因数

NO WASTE

宽和高都必须被 d 整除。

SAME SIZE

所有小正方形使用同一个 d。

MAX COUNT

问的是数量最多,不是正方形最大。

最大数量,意味着选择最小的合法边长

正方形数量
W / d × H / d = WH / d²

W、H 固定时,d 越小,数量越多。

合法边长从哪里找?
x = gcd(W, H)

W、H 的所有公共因数,都藏在最大公约数 x 的因数中。

问题变成:找 x 的最小因数 d ≥ 2 → 它就是 x 的最小质因数

令 x = gcd(W,H),接下来只有三种情况

x = 1

无合法边长

答案 = 0
x 是质数

d = x

(W/x) × (H/x)
x 是合数

找最小因数 i

(W/i) × (H/i)

从 2 开始枚举,第一个整除 x 的 i,就是最小质因数。

先准备两个工具:gcd 与质数判断

核心函数
long long gcd(long long a, long long b) {
    // 欧几里得算法:不断用余数缩小问题
    return b > 0 ? gcd(b, a % b) : a;
}

int isPrime(long long x) {
    // 因数总是成对出现,只需检查到 sqrt(x)
    for (long long i = 2; i * i <= x; i++) {
        if (x % i == 0) return 0;
    }
    return 1;
}
long long gcd(long long a, long long b) {
    return b > 0 ? gcd(b, a % b) : a;
}

bool isPrime(long long x) {
    for (long long i = 2; i * i <= x; i++) {
        // 找到一个非平凡因数,x 就不是质数
        if (x % i == 0) return false;
    }
    return true;
}
from math import gcd, isqrt

def is_prime(x):
    # 只检查到整数平方根
    for i in range(2, isqrt(x) + 1):
        if x % i == 0:
            return False
    return True

主流程只是在实现刚才的三种情况

保留原算法
long long w, h;
int main() {
    scanf("%lld %lld", &w, &h);
    long long x = gcd(w, h);

    // gcd 为 1:没有大于等于 2 的公共边长
    if (x == 1) {
        printf("0\n");
        return 0;
    }
    // x 为质数:最小合法公约数就是 x 自己
    if (isPrime(x)) {
        printf("%lld\n", (w / x) * (h / x));
        return 0;
    }
    // 从小到大遇到的第一个因数,就是最小合法边长
    for (long long i = 2; i * i <= x; i++) {
        if (x % i == 0) {
            printf("%lld\n", (w / i) * (h / i));
            return 0;
        }
    }
}
long long w, h;
int main() {
    cin >> w >> h;
    long long x = gcd(w, h);

    if (x == 1) {
        cout << 0 << endl;
        return 0;
    }
    if (isPrime(x)) {
        cout << (w / x) * (h / x) << endl;
        return 0;
    }
    for (long long i = 2; i * i <= x; i++) {
        if (x % i == 0) {
            cout << (w / i) * (h / i) << endl;
            return 0;
        }
    }
}
w, h = map(int, input().split())
x = gcd(w, h)

if x == 1:
    print(0)
elif is_prime(x):
    # x 是质数时,最小合法边长只能是 x
    print((w // x) * (h // x))
else:
    for i in range(2, isqrt(x) + 1):
        if x % i == 0:
            # 第一个因数就是最小合法边长
            print((w // i) * (h // i))
            break

离开前,只需要带走这五件事

01

一定要动手写;“看懂”不是终点。

02

一定要做 OJ;也别忽略课堂、笔试与项目。

03

报错是线索;先读第一条有意义的信息。

04

AI 可以协助;正确性与提交责任仍属于你。

05

路线可以探索;不要把大学变成“五线作战”。

LONG-TERM BUFF

稳定练习
比偶尔爆肝更强

保证睡眠、运动、休息和用眼;编程不是连续坐得越久越强。

现在,轮到你的问题

环境 + 代码 + 输入 + 错误信息 + 已经尝试的方法

“跑不了”是开头;这些信息能让别人真正帮到你。

想把“会写代码”
继续变成“能做东西”

欢迎加入厦门大学
OpenHarmony 社团

QQ群:1053448419

扫码加入群聊,认识同样想动手做项目的人。

厦门大学OpenHarmony社团QQ群二维码
01 / 01