<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>奇数约数与偶数约数 - 完整教学</title>
<style>
* {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
html,
body {
margin: 0;
padding: 0;
background: #F0F4F8;
overflow: hidden;
height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
-webkit-text-size-adjust: 100%;
}
#app {
height: 100vh;
width: 100%;
max-width: 480px;
margin: 0 auto;
background: #fff;
display: flex;
flex-direction: column;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
}
.content-area {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding-bottom: 80px;
-webkit-overflow-scrolling: touch;
/* 隐藏滚动条但保持滚动功能 */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
}
.content-area::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera */
}
/* 顶部标签栏 */
.top-tabs {
display: flex;
background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
padding: 10px 10px 0 10px;
gap: 5px;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
}
.top-tab {
flex-shrink: 0;
padding: 10px 12px;
border-radius: 12px 12px 0 0;
font-size: 12px;
font-weight: bold;
color: rgba(255, 255, 255, 0.7);
cursor: pointer;
transition: all 0.3s;
background: rgba(255, 255, 255, 0.1);
min-width: 90px;
text-align: center;
}
.top-tab.active {
background: white;
color: #7C3AED;
transform: translateY(-2px);
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
}
/* 底部导航 */
.bottom-nav {
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: 480px;
height: 70px;
background: white;
border-top: 1px solid #e0e0e0;
display: flex;
justify-content: space-around;
align-items: center;
z-index: 1000;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
}
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 8px;
transition: all 0.3s;
color: #64748B;
}
.nav-item.active {
color: #8B5CF6;
}
.nav-icon {
font-size: 24px;
margin-bottom: 4px;
}
.nav-label {
font-size: 12px;
font-weight: 500;
}
/* 通用样式 */
.page-container {
padding: 20px;
}
.section-title {
font-size: 20px;
font-weight: 800;
color: #1E293B;
margin: 20px 0 15px 0;
display: flex;
align-items: center;
gap: 8px;
}
.card {
background: white;
border-radius: 12px;
padding: 20px;
margin-bottom: 15px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
border: 1px solid #E2E8F0;
}
.tag {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
margin-bottom: 8px;
}
.tag-blue {
background: #E0F2FE;
color: #0284C7;
}
.tag-green {
background: #D1FAE5;
color: #065F46;
}
.tag-orange {
background: #FFEDD5;
color: #C2410C;
}
.tag-purple {
background: #F3E8FF;
color: #7C3AED;
}
.tag-pink {
background: #FCE7F3;
color: #BE185D;
}
.formula-box {
background: linear-gradient(135deg, #F3E8FF 0%, #E9D5FF 100%);
padding: 20px;
border-radius: 12px;
border: 3px solid #8B5CF6;
margin: 15px 0;
text-align: center;
}
.formula-title {
font-size: 14px;
font-weight: bold;
color: #7C3AED;
margin-bottom: 10px;
}
.formula-content {
font-size: 18px;
font-weight: bold;
color: #1E293B;
}
.speak-btn {
background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
color: white;
border: none;
padding: 12px 20px;
border-radius: 20px;
font-size: 14px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
box-shadow: 0 4px 10px rgba(139, 92, 246, 0.3);
width: 100%;
}
/* 动画舞台 */
.anim-stage {
background: #1E293B;
border-radius: 16px;
padding: 25px 15px;
min-height: 400px;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
border: 2px solid #334155;
margin: 15px 0;
}
.anim-text {
color: white;
margin-top: auto;
font-size: 14px;
font-weight: bold;
text-align: center;
min-height: 60px;
background: rgba(0, 0, 0, 0.4);
padding: 12px 15px;
border-radius: 20px;
backdrop-filter: blur(4px);
width: 100%;
display: flex;
align-items: center;
justify-content: center;
line-height: 1.5;
}
.step-controls {
display: flex;
gap: 10px;
margin-bottom: 15px;
justify-content: center;
flex-wrap: wrap;
}
.step-btn {
background: #8B5CF6;
color: white;
border: none;
padding: 8px 20px;
border-radius: 20px;
font-weight: bold;
font-size: 13px;
cursor: pointer;
transition: all 0.2s;
}
.step-btn:disabled {
background: #CBD5E1;
cursor: not-allowed;
}
.step-btn:active:not(:disabled) {
transform: scale(0.95);
}
/* 计算演示 */
.calc-demo {
color: white;
width: 100%;
margin-top: 20px;
}
.calc-step {
background: rgba(255, 255, 255, 0.1);
padding: 15px;
border-radius: 10px;
margin-bottom: 15px;
opacity: 0;
border: 2px solid transparent;
}
.calc-step.active {
border-color: #8B5CF6;
background: rgba(139, 92, 246, 0.2);
}
.calc-equation {
font-size: 16px;
text-align: center;
margin-bottom: 8px;
}
.calc-highlight {
color: #FCD34D;
font-size: 20px;
font-weight: bold;
}
.calc-explanation {
font-size: 12px;
color: #CBD5E1;
text-align: center;
margin-top: 5px;
}
/* 视觉演示 */
.visual-demo {
width: 100%;
margin-top: 20px;
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
}
.divisor-grid {
display: flex;
flex-wrap: wrap;
gap: 8px;
justify-content: center;
max-width: 100%;
}
.divisor-box {
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
font-size: 16px;
font-weight: bold;
color: white;
background: #3B82F6;
opacity: 0;
}
.divisor-odd {
background: #F59E0B;
}
.divisor-even {
background: #10B981;
}
.split-container {
display: flex;
gap: 20px;
width: 100%;
justify-content: center;
}
.split-section {
flex: 1;
max-width: 45%;
}
.split-title {
color: white;
font-size: 14px;
font-weight: bold;
text-align: center;
margin-bottom: 10px;
padding: 8px;
border-radius: 8px;
}
.title-odd {
background: #F59E0B;
}
.title-even {
background: #10B981;
}
/* 练习题样式 */
.question-card {
background: white;
border-radius: 16px;
padding: 20px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
margin-bottom: 15px;
}
.question-text {
font-size: 16px;
font-weight: bold;
margin-bottom: 15px;
line-height: 1.6;
color: #1E293B;
}
.answer-input {
width: 100%;
padding: 12px;
border: 2px solid #E2E8F0;
border-radius: 8px;
font-size: 16px;
margin-bottom: 10px;
}
.submit-btn {
background: #8B5CF6;
color: white;
border: none;
padding: 12px;
border-radius: 8px;
width: 100%;
font-weight: bold;
font-size: 16px;
cursor: pointer;
}
.feedback-box {
margin-top: 10px;
padding: 12px;
border-radius: 8px;
font-size: 13px;
line-height: 1.6;
}
.feedback-correct {
background: #ECFDF5;
color: #047857;
border: 2px solid #10B981;
}
.feedback-wrong {
background: #FEF2F2;
color: #B91C1C;
border: 2px solid #EF4444;
}
.concept-card {
background: linear-gradient(135deg, #DBEAFE 0%, #BFDBFE 100%);
border: 2px solid #3B82F6;
border-radius: 12px;
padding: 15px;
margin: 15px 0;
}
.concept-title {
font-size: 15px;
font-weight: bold;
color: #1E40AF;
margin-bottom: 10px;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.08);
}
}
@keyframes slideIn {
from {
transform: translateX(-20px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<!-- Page 1: 核心原理 -->
<div v-show="currentPage === 1">
<div class="top-tabs">
<div class="top-tab" :class="{active: theoryTab === 'intro'}" @click="theoryTab = 'intro'">
为什么学
</div>
<div class="top-tab" :class="{active: theoryTab === 'odd'}" @click="theoryTab = 'odd'">
奇数约数
</div>
<div class="top-tab" :class="{active: theoryTab === 'even'}" @click="theoryTab = 'even'">
偶数约数
</div>
</div>
<div class="page-container">
<!-- 引入 -->
<div v-show="theoryTab === 'intro'">
<div class="section-title">🎯 为什么要学奇偶约数</div>
<div class="card">
<div class="tag tag-blue">研究目标</div>
<p style="font-size: 14px; color: #334155; line-height: 1.8; margin-top: 10px;">
我们已经知道如何求一个数的<strong>所有约数个数</strong>。<br>
现在,我们要更精细地研究:这些约数中,<br>
• 有多少个是<strong style="color: #F59E0B;">奇数</strong>?<br>
• 有多少个是<strong style="color: #10B981;">偶数</strong>?
</p>
</div>
<div class="card">
<div class="tag tag-purple">核心技巧</div>
<p style="font-size: 14px; color: #334155; line-height: 1.8; margin-top: 10px;">
为了方便区分奇偶,我们把素因数分解式中的<strong>2单独提取出来</strong>:
</p>
<div
style="background: #F3E8FF; padding: 15px; border-radius: 8px; margin: 10px 0; text-align: center; font-size: 16px; font-weight: bold;">
$N = 2^a \times M$
</div>
<div style="font-size: 13px; color: #64748B; line-height: 1.6;">
其中:<br>
• $a \ge 0$ 是2的指数<br>
• $M$ 是<strong>奇数部分</strong>(所有素因数 ≥ 3)
</div>
</div>
<div class="card">
<div class="tag tag-orange">经典例子:72</div>
<p style="font-size: 13px; color: #64748B; margin: 10px 0;">
让我们看看 72 的约数如何分类
</p>
<div class="step-controls">
<button class="step-btn" @click="animateIntro">▶️ 演示分类过程</button>
</div>
<div class="anim-stage">
<div class="visual-demo" id="intro-demo">
<!-- 动画将在这里生成 -->
</div>
<div class="anim-text" id="intro-text">点击按钮开始演示</div>
</div>
</div>
<button class="speak-btn" @click="speakIntro">
🔊 听讲解
</button>
</div>
<!-- 奇数约数 -->
<div v-show="theoryTab === 'odd'">
<div class="section-title">🟡 奇数约数的个数</div>
<div class="concept-card">
<div class="concept-title">核心概念</div>
<div style="font-size: 14px; color: #1E40AF; line-height: 1.8;">
一个数是<strong>奇数</strong>,意味着它的素因数分解中<strong>绝对不能出现因子2</strong>。
</div>
</div>
<div class="formula-box">
<div class="formula-title">★ 奇数约数个数公式 ★</div>
<div class="formula-content">
若 $N = 2^a \times M$,则<br>
$\tau_{\text{奇}}(N) = \tau(M)$
</div>
</div>
<div class="card">
<div class="tag tag-blue">公式推导</div>
<div style="font-size: 14px; color: #334155; line-height: 1.8; margin-top: 10px;">
<p><strong>步骤1:</strong>奇数约数不能含因子2</p>
<p><strong>步骤2:</strong>所以奇数约数只能由 $M$ 的素因数组成</p>
<p><strong>步骤3:</strong>$N$ 的所有奇数约数 = $M$ 的所有约数</p>
<p><strong>结论:</strong>$\tau_{\text{奇}}(N) = \tau(M)$</p>
</div>
</div>
<div class="card">
<div class="tag tag-purple">动画演示:720的奇数约数</div>
<p style="font-size: 13px; color: #64748B; margin: 10px 0;">
$720 = 2^4 \times 3^2 \times 5$
</p>
<div class="step-controls">
<button class="step-btn" @click="animateOdd">▶️ 演示计算过程</button>
</div>
<div class="anim-stage">
<div class="calc-demo" id="odd-demo">
<!-- 动画将在这里生成 -->
</div>
<div class="anim-text" id="odd-text">点击按钮开始演示</div>
</div>
</div>
<button class="speak-btn" @click="speakOdd">
🔊 听讲解
</button>
</div>
<!-- 偶数约数 -->
<div v-show="theoryTab === 'even'">
<div class="section-title">🟢 偶数约数的个数</div>
<div class="concept-card">
<div class="concept-title">核心概念</div>
<div style="font-size: 14px; color: #1E40AF; line-height: 1.8;">
一个数是<strong>偶数</strong>,意味着它<strong>至少含有一个因子2</strong>。
</div>
</div>
<div class="formula-box">
<div class="formula-title">★ 偶数约数个数公式 ★</div>
<div class="formula-content" style="font-size: 16px;">
$\tau_{\text{偶}}(N) = a \times \tau_{\text{奇}}(N)$<br>
$= a \times \tau(M)$
</div>
</div>
<div class="card">
<div class="tag tag-blue">方法一:减法(简单)</div>
<div
style="background: #EFF6FF; padding: 15px; border-radius: 8px; margin: 10px 0; text-align: center;">
$\tau_{\text{偶}}(N) = \tau(N) - \tau_{\text{奇}}(N)$
</div>
<p style="font-size: 13px; color: #64748B;">用总数减去奇数个数</p>
</div>
<div class="card">
<div class="tag tag-green">方法二:直接计算(推导)</div>
<div style="font-size: 14px; color: #334155; line-height: 1.8; margin-top: 10px;">
<p><strong>偶数约数的结构:</strong>$d_{\text{偶}} = 2^i \times d_{\text{奇}}$</p>
<p>其中:</p>
<div style="background: #F0FDF4; padding: 12px; border-radius: 8px; margin: 10px 0;">
• $d_{\text{奇}}$ 是 $M$ 的一个约数,有 $\tau(M)$ 种选择<br>
• $i$ 满足 $1 \le i \le a$(必须 ≥1 才是偶数),有 $a$ 种选择
</div>
<p><strong>根据乘法原理:</strong>$\tau_{\text{偶}}(N) = a \times \tau(M)$</p>
</div>
</div>
<div class="card">
<div class="tag tag-purple">动画演示:720的偶数约数</div>
<p style="font-size: 13px; color: #64748B; margin: 10px 0;">
$720 = 2^4 \times 3^2 \times 5$
</p>
<div class="step-controls">
<button class="step-btn" @click="animateEven">▶️ 演示计算过程</button>
</div>
<div class="anim-stage">
<div class="calc-demo" id="even-demo">
<!-- 动画将在这里生成 -->
</div>
<div class="anim-text" id="even-text">点击按钮开始演示</div>
</div>
</div>
<button class="speak-btn" @click="speakEven">
🔊 听讲解
</button>
</div>
</div>
</div>
<!-- Page 2: 5道经典例题 -->
<div v-show="currentPage === 2">
<div class="top-tabs">
<div class="top-tab" :class="{active: exampleIndex === index}"
v-for="(ex, index) in classicExamples" :key="'tab-' + index" @click="switchExample(index)">
例题{{ index + 1 }}
</div>
</div>
<div class="page-container">
<div v-for="(ex, index) in classicExamples" :key="'example-' + index"
v-show="exampleIndex === index">
<div class="section-title">{{ ex.title }}</div>
<div class="card">
<div class="tag tag-blue">题目</div>
<div class="question-text" v-html="ex.question"></div>
</div>
<div class="card">
<div class="tag tag-purple">分步解析(动画演示)</div>
<div class="step-controls">
<button class="step-btn" @click="prevExampleStep(index)"
:disabled="exampleSteps[index] === 0">
◀ 上一步
</button>
<button class="step-btn" @click="nextExampleStep(index)"
:disabled="exampleSteps[index] >= ex.steps.length - 1">
下一步 ▶
</button>
<button class="step-btn" @click="resetExampleStep(index)" style="background: #64748B;">
🔄 重置
</button>
<button class="step-btn" @click="speakExample(index)" style="background: #10B981;">
🔊 语音
</button>
</div>
<div class="anim-stage">
<div class="calc-demo">
<div v-for="(step, sIndex) in ex.steps" :key="'step-' + sIndex" class="calc-step"
:class="{active: exampleSteps[index] === sIndex}"
:style="{opacity: exampleSteps[index] >= sIndex ? 1 : 0}">
<div class="calc-equation" v-html="step.equation"></div>
<div class="calc-explanation">{{ step.explanation }}</div>
</div>
</div>
<div class="anim-text">
{{ exampleSteps[index] < ex.steps.length ? ex.steps[exampleSteps[index]].text
: '已完成所有步骤' }} </div>
</div>
</div>
<div class="card">
<div class="tag tag-green">答案</div>
<div style="background: #ECFDF5; padding: 15px; border-radius: 8px; border-left: 3px solid #10B981;"
v-html="ex.answer"></div>
</div>
</div>
</div>
</div>
<!-- Page 3: 10道练习题 -->
<div v-show="currentPage === 3" class="page-container">
<div class="section-title">✏️ 10道课程练习</div>
<div v-if="!practiceDone">
<div class="question-card">
<div class="tag tag-blue">练习 {{ currentPracticeIndex + 1 }}/10</div>
<div class="question-text" v-html="practiceQuestions[currentPracticeIndex].question"></div>
<input type="text" class="answer-input" v-model="userAnswer" placeholder="输入答案"
@keyup.enter="checkPracticeAnswer" :disabled="practiceAnswered">
<button class="submit-btn" @click="checkPracticeAnswer" v-if="!practiceAnswered">
提交答案
</button>
<div v-if="practiceAnswered" class="feedback-box"
:class="isPracticeCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isPracticeCorrect" style="font-weight: bold; margin-bottom: 5px;">🎉 正确!
</div>
<div v-else style="font-weight: bold; margin-bottom: 5px;">💡 答案:{{
practiceQuestions[currentPracticeIndex].answer }}</div>
<div v-html="practiceQuestions[currentPracticeIndex].explanation"></div>
</div>
<button v-if="practiceAnswered" class="submit-btn" @click="nextPractice"
style="margin-top: 10px;">
{{ currentPracticeIndex < 9 ? '下一题 →' : '完成练习 🎯' }} </button>
</div>
</div>
<div v-else class="card" style="text-align: center; padding: 40px 20px;">
<div style="font-size: 60px; margin-bottom: 20px;">🏆</div>
<h2 style="color: #1E293B; margin-bottom: 10px;">练习完成!</h2>
<p style="font-size: 18px; color: #64748B; margin-bottom: 30px;">得分:{{ practiceScore }}/100</p>
<button class="submit-btn" @click="switchPage(4)">挑战杯赛真题 →</button>
</div>
</div>
<!-- Page 4: 10道杯赛真题 -->
<div v-show="currentPage === 4" class="page-container">
<div class="section-title">🏆 10道杯赛真题</div>
<div class="card" style="background: linear-gradient(135deg, #F3E8FF 0%, #E9D5FF 100%);">
<div style="font-size: 14px; color: #6B21A8; line-height: 1.6;">
<strong>💡 提示:</strong>这些题目来自华杯赛、希望杯、迎春杯等真题。<br>
需要灵活运用奇偶约数的性质和公式!
</div>
</div>
<div v-if="!olympiadDone">
<div class="question-card">
<div class="tag tag-purple">🏆 杯赛真题 {{ currentOlympiadIndex + 1 }}/10</div>
<div class="question-text" v-html="olympiadQuestions[currentOlympiadIndex].question"></div>
<div v-if="olympiadQuestions[currentOlympiadIndex].hint"
style="background: #F3E8FF; padding: 12px; border-radius: 6px; margin-bottom: 10px; font-size: 13px;">
<strong>💡 提示:</strong>{{ olympiadQuestions[currentOlympiadIndex].hint }}
</div>
<input type="text" class="answer-input" v-model="userOlympiadAnswer" placeholder="输入答案"
@keyup.enter="checkOlympiadAnswer" :disabled="olympiadAnswered">
<button class="submit-btn" @click="checkOlympiadAnswer" v-if="!olympiadAnswered">
提交答案
</button>
<div v-if="olympiadAnswered" class="feedback-box"
:class="isOlympiadCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isOlympiadCorrect" style="font-weight: bold; margin-bottom: 5px;">🎉 正确!太棒了!
</div>
<div v-else style="font-weight: bold; margin-bottom: 5px;">💡 正确答案:{{
olympiadQuestions[currentOlympiadIndex].answer }}</div>
<div style="margin-top: 10px;"><strong>详细解析:</strong></div>
<div v-html="olympiadQuestions[currentOlympiadIndex].explanation"></div>
</div>
<button v-if="olympiadAnswered" class="submit-btn" @click="nextOlympiad"
style="margin-top: 10px;">
{{ currentOlympiadIndex < 9 ? '下一题 →' : '查看成绩 📚' }} </button>
</div>
</div>
<div v-else class="card" style="text-align: center; padding: 40px 20px;">
<div style="font-size: 60px; margin-bottom: 20px;">🥇</div>
<h2 style="color: #1E293B; margin-bottom: 10px;">杯赛真题通关!</h2>
<p style="font-size: 18px; color: #64748B; margin-bottom: 30px;">得分:{{ olympiadScore }}/100</p>
<p style="font-size: 14px; color: #64748B;">你已经掌握了奇数约数与偶数约数!</p>
</div>
</div>
</div>
<!-- 底部导航 -->
<div class="bottom-nav">
<div class="nav-item" :class="{active: currentPage === 1}" @click="switchPage(1)">
<div class="nav-icon">📖</div>
<div class="nav-label">原理</div>
</div>
<div class="nav-item" :class="{active: currentPage === 2}" @click="switchPage(2)">
<div class="nav-icon">📚</div>
<div class="nav-label">例题</div>
</div>
<div class="nav-item" :class="{active: currentPage === 3}" @click="switchPage(3)">
<div class="nav-icon">✏️</div>
<div class="nav-label">练习</div>
</div>
<div class="nav-item" :class="{active: currentPage === 4}" @click="switchPage(4)">
<div class="nav-icon">🏆</div>
<div class="nav-label">杯赛</div>
</div>
</div>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
currentPage: 1,
theoryTab: 'intro',
exampleIndex: 0,
// 例题步骤
exampleSteps: [0, 0, 0, 0, 0],
// 5道经典例题
classicExamples: [
{
title: '例题1:计算720的奇数约数个数',
question: '计算 $N=720$ 的奇数约数的个数。',
steps: [
{ equation: '第1步:素因数分解', explanation: '从小到大分解', text: '步骤1:开始质因数分解' },
{ equation: '$720 = 72 \\times 10$', explanation: '拆分成熟悉的数', text: '步骤2:拆分数字' },
{ equation: '$= (2^3 \\times 3^2) \\times (2 \\times 5)$', explanation: '分别分解', text: '步骤3:分别分解' },
{ equation: '<span class="calc-highlight">$= 2^4 \\times 3^2 \\times 5^1$</span>', explanation: '合并同类项', text: '步骤4:得到标准形式' },
{ equation: '第2步:确定奇数部分 $M$', explanation: '去掉2的幂次', text: '步骤5:提取奇数部分' },
{ equation: '$M = 3^2 \\times 5^1$', explanation: '只保留奇质因数', text: '步骤6:得到M' },
{ equation: '第3步:计算 $\\tau_{\\text{奇}}(N)$', explanation: '套用公式', text: '步骤7:套用公式' },
{ equation: '$\\tau_{\\text{奇}}(N) = \\tau(M)$', explanation: '奇数约数 = M的约数', text: '步骤8:应用公式' },
{ equation: '<span class="calc-highlight">$= (2+1)(1+1) = 6$</span>', explanation: '计算结果', text: '步骤9:得出答案' }
],
answer: '<strong style="color: #8B5CF6; font-size: 18px;">答案:6个奇数约数</strong>',
voice: '求720的奇数约数个数。第一步,素因数分解。720等于2的4次方乘以3的平方乘以5。第二步,确定奇数部分M。去掉2的幂次,M等于3的平方乘以5。第三步,计算奇数约数个数。套用公式,奇数约数个数等于M的约数个数,等于括号2加1括号乘以括号1加1括号,等于3乘以2,等于6。答案是6个。'
},
{
title: '例题2:计算720的偶数约数个数',
question: '计算 $N=720$ 的偶数约数的个数。',
steps: [
{ equation: '第1步:利用上题结果', explanation: '已知条件', text: '步骤1:回顾已知' },
{ equation: '$a = 4$(2的指数)', explanation: '从720=2⁴×...得到', text: '步骤2:a=4' },
{ equation: '$\\tau_{\\text{奇}}(N) = 6$', explanation: '上题结果', text: '步骤3:奇数约数6个' },
{ equation: '第2步:套用偶数约数公式', explanation: '使用核心公式', text: '步骤4:准备计算' },
{ equation: '$\\tau_{\\text{偶}}(N) = a \\times \\tau_{\\text{奇}}(N)$', explanation: '偶数约数公式', text: '步骤5:公式' },
{ equation: '$= 4 \\times 6$', explanation: '代入数值', text: '步骤6:代入' },
{ equation: '<span class="calc-highlight">$= 24$</span>', explanation: '计算结果', text: '步骤7:得出答案' }
],
answer: '<strong style="color: #8B5CF6; font-size: 18px;">答案:24个偶数约数</strong>',
voice: '求720的偶数约数个数。利用上题结果,a等于4,奇数约数个数等于6。套用偶数约数公式,偶数约数个数等于a乘以奇数约数个数,等于4乘以6,等于24。答案是24个。'
},
{
title: '例题3:奇偶约数比值',
question: '已知 $N=2^5 \\times 7^2$,求 $N$ 的偶数约数个数与奇数约数个数之比。',
steps: [
{ equation: '第1步:计算奇数约数个数', explanation: '先求奇数', text: '步骤1:求奇数约数' },
{ equation: '奇数部分 $M = 7^2$', explanation: '去掉2⁵', text: '步骤2:M=7²' },
{ equation: '$\\tau_{\\text{奇}}(N) = \\tau(7^2) = 2+1 =$ <span class="calc-highlight">3</span>', explanation: '计算M的约数', text: '步骤3:奇数3个' },
{ equation: '第2步:计算偶数约数个数', explanation: '再求偶数', text: '步骤4:求偶数约数' },
{ equation: '$\\tau_{\\text{偶}}(N) = a \\times \\tau_{\\text{奇}}(N)$', explanation: '套用公式', text: '步骤5:套用公式' },
{ equation: '<span class="calc-highlight">$= 5 \\times 3 = 15$</span>', explanation: 'a=5', text: '步骤6:偶数15个' },
{ equation: '第3步:求比值', explanation: '偶数 : 奇数', text: '步骤7:计算比值' },
{ equation: '<span class="calc-highlight">$15 : 3 = 5:1$</span>', explanation: '化简比值', text: '步骤8:得出答案' },
{ equation: '注:比值恒等于 $a$', explanation: '重要性质', text: '步骤9:总结规律' }
],
answer: '<strong style="color: #8B5CF6; font-size: 18px;">答案:5:1</strong><br>规律:偶数与奇数约数个数之比 = 2的指数 $a$',
voice: '已知N等于2的5次方乘以7的平方,求偶数约数个数与奇数约数个数之比。第一步,计算奇数约数个数。奇数部分M等于7的平方,奇数约数个数等于2加1,等于3。第二步,计算偶数约数个数。等于a乘以奇数约数个数,等于5乘以3,等于15。第三步,求比值。15比3,等于5比1。注意,比值恒等于2的指数a。'
},
{
title: '例题4:奇数的偶数约数',
question: '如果一个正整数 $N$ 是奇数,那么它拥有的偶数约数个数是多少?',
steps: [
{ equation: '第1步:理解"奇数"的含义', explanation: '关键条件', text: '步骤1:理解题意' },
{ equation: '$N$ 是奇数 $\\implies$ 不含因子2', explanation: '奇数定义', text: '步骤2:N是奇数' },
{ equation: '即:2的指数 $a = 0$', explanation: 'a=0', text: '步骤3:a=0' },
{ equation: '第2步:套用偶数约数公式', explanation: '使用公式', text: '步骤4:套用公式' },
{ equation: '$\\tau_{\\text{偶}}(N) = a \\times \\tau_{\\text{奇}}(N)$', explanation: '核心公式', text: '步骤5:公式' },
{ equation: '$= 0 \\times \\tau_{\\text{奇}}(N)$', explanation: '代入a=0', text: '步骤6:代入a=0' },
{ equation: '<span class="calc-highlight">$= 0$</span>', explanation: '任何数乘0等于0', text: '步骤7:得出答案' }
],
answer: '<strong style="color: #8B5CF6; font-size: 18px;">答案:0个</strong><br>结论:奇数没有偶数约数',
voice: '如果一个正整数N是奇数,那么它拥有的偶数约数个数是多少。第一步,理解奇数的含义。N是奇数,意味着不含因子2,即2的指数a等于0。第二步,套用偶数约数公式。偶数约数个数等于a乘以奇数约数个数,等于0乘以奇数约数个数,等于0。答案是0个。结论,奇数没有偶数约数。'
},
{
title: '例题5:奇数约数个数为1',
question: '已知一个正整数 $N$ 的奇数约数个数 $\\tau_{\\text{奇}}(N)=1$,请问关于 $N$ 可以得出什么结论?',
steps: [
{ equation: '第1步:应用奇数约数公式', explanation: '从公式入手', text: '步骤1:应用公式' },
{ equation: '$\\tau_{\\text{奇}}(N) = \\tau(M) = 1$', explanation: '题目条件', text: '步骤2:τ(M)=1' },
{ equation: '第2步:分析 $\\tau(M) = 1$ 的含义', explanation: 'M的约数只有1个', text: '步骤3:分析M' },
{ equation: '一个数的约数个数为1', explanation: '特殊情况', text: '步骤4:特殊情况' },
{ equation: '<span class="calc-highlight">$\\implies$ 该数只能是 $1$</span>', explanation: '唯一可能', text: '步骤5:M=1' },
{ equation: '所以 $M = 1$', explanation: '确定M', text: '步骤6:确定M=1' },
{ equation: '第3步:推出 $N$ 的形式', explanation: 'N的结构', text: '步骤7:推出N' },
{ equation: '$N = 2^a \\times M = 2^a \\times 1$', explanation: 'M=1代入', text: '步骤8:N=2^a' },
{ equation: '<span class="calc-highlight">$N = 2^a$ ($a \\ge 0$)</span>', explanation: '最终结论', text: '步骤9:得出结论' }
],
answer: '<strong style="color: #8B5CF6; font-size: 18px;">答案:$N$ 只能是2的幂次</strong><br>即 $N = 2^a$($a \\ge 0$),包括 1, 2, 4, 8, 16, ...',
voice: '已知一个正整数N的奇数约数个数等于1,请问关于N可以得出什么结论。第一步,应用奇数约数公式。奇数约数个数等于M的约数个数,等于1。第二步,分析M的约数个数等于1的含义。一个数的约数个数为1,该数只能是1。所以M等于1。第三步,推出N的形式。N等于2的a次方乘以M,等于2的a次方乘以1,等于2的a次方。结论,N只能是2的幂次,包括1、2、4、8、16等等。'
}
],
// 练习题
currentPracticeIndex: 0,
practiceScore: 0,
practiceAnswered: false,
isPracticeCorrect: false,
userAnswer: '',
practiceDone: false,
practiceQuestions: [
{ question: '偶数约数个数是奇数约数个数的 $3$ 倍,且 $N=2^a \\times 5^2$,求 $N$ 的总约数个数', answer: '12', explanation: '$\\tau_{\\text{奇}}(N) = 2+1 = 3$<br>$\\tau_{\\text{偶}}(N) = 3 \\times \\tau_{\\text{奇}}(N)$ → $a=3$<br>$\\tau(N) = (3+1)(2+1) = <strong>12</strong>$' },
{ question: '一个正整数 $N$ 有 $6$ 个奇数约数和 $18$ 个偶数约数,求 $N$ 中 $2$ 的指数 $a$', answer: '3', explanation: '$a = \\tau_{\\text{偶}}(N) / \\tau_{\\text{奇}}(N) = 18/6 = <strong>3</strong>$' },
{ question: '如果完全平方数 $N$ 恰有 $15$ 个奇数约数,那么 $N$ 至少有多少个偶数约数?', answer: '30', explanation: '$N$ 是完全平方数 → $a$ 必须是偶数<br>$N$ 有偶数约数 → $a \\ge 1$<br>最小偶数 $a=2$<br>$\\tau_{\\text{偶}}(N) = 2 \\times 15 = <strong>30</strong>$' },
{ question: '$N$ 是 $8$ 的倍数,且 $\\tau_{\\text{奇}}(N)=5$,求 $\\tau_{\\text{偶}}(N)$ 的最小值', answer: '15', explanation: '$8$ 的倍数 → $a \\ge 3$<br>$\\tau_{\\text{偶}}(N) = a \\times 5$<br>最小值:$a=3$ 时,$3 \\times 5 = <strong>15</strong>$' },
{ question: '下列哪个数恰有 $6$ 个奇数约数?90, 108, 120, 144(输入数字)', answer: '90', explanation: '$90=2 \\times 3^2 \\times 5$ → $\\tau_{\\text{奇}}=(2+1)(1+1)=6$ ✓<br>$108=2^2 \\times 3^3$ → $\\tau_{\\text{奇}}=4$<br>$120=2^3 \\times 3 \\times 5$ → $\\tau_{\\text{奇}}=4$<br>$144=2^4 \\times 3^2$ → $\\tau_{\\text{奇}}=3$' },
{ question: '如果 $N=p^k$($p$ 为奇素数,$k \\ge 1$),那么 $\\tau_{\\text{偶}}(N)$ 是多少?', answer: '0', explanation: '$N$ 是奇数 → $a=0$<br>$\\tau_{\\text{偶}}(N) = a \\times \\tau_{\\text{奇}}(N) = <strong>0</strong>$' },
{ question: '已知 $N$ 有 $4$ 个奇数约数和 $24$ 个总约数,求 $2$ 的指数 $a$', answer: '5', explanation: '$\\tau_{\\text{偶}}(N) = 24 - 4 = 20$<br>$a = 20/4 = <strong>5</strong>$' },
{ question: '如果 $N=2^6 \\times 3^6$,求 $\\tau_{\\text{偶}}(N)$', answer: '42', explanation: '$a=6$<br>$\\tau_{\\text{奇}}(N) = \\tau(3^6) = 7$<br>$\\tau_{\\text{偶}}(N) = 6 \\times 7 = <strong>42</strong>$' },
{ question: '已知 $N = 360 \\times k$,如果 $N$ 恰有 $15$ 个奇数约数,求最小的正整数 $k$', answer: '45', explanation: '$360 = 2^3 \\times 3^2 \\times 5$<br>设 $k=3^y \\times 5^z$<br>$(3+y)(2+z)=15=3 \\times 5$<br>$y=2, z=1$ → $k = 3^2 \\times 5 = <strong>45</strong>$' },
{ question: '$N < 100$,总约数 $12$ 个,偶数约数 $8$ 个,有多少个不同的可能值?', answer: '2', explanation: '$\\tau_{\\text{奇}}(N) = 12-8 = 4$,$a = 8/4 = 2$<br>$N=4M$,$M<25$,$\\tau(M)=4$<br>$M=15$ (60) 或 $M=21$ (84)<br>共 <strong>2</strong> 个' }
],
// 杯赛真题
currentOlympiadIndex: 0,
olympiadScore: 0,
olympiadAnswered: false,
isOlympiadCorrect: false,
userOlympiadAnswer: '',
olympiadDone: false,
olympiadQuestions: [
{
question: '求满足 $\\tau_{\\text{奇}}(N)=3$ 且 $\\tau_{\\text{偶}}(N)=6$ 的最小正整数 $N$。',
answer: '36',
hint: '先求a,再求M',
explanation: '$a = 6/3 = 2$ → $N=2^2 \\times M$<br>$\\tau(M)=3$ → $M=p^2$<br>最小奇素数 $p=3$ → $M=9$<br>$N = 4 \\times 9 = <strong>36</strong>$'
},
{
question: '正整数 $N$ 有 $10$ 个偶数约数。如果 $\\tau_{\\text{奇}}(N)$ 是素数,求 $N$ 的最小值。',
answer: '96',
hint: 'a×τ奇(N)=10,τ奇是素数',
explanation: '$a \\times \\tau_{\\text{奇}}(N)=10$<br>$\\tau_{\\text{奇}}$ 是素数 → 2 或 5<br>Case1: $\\tau_{\\text{奇}}=2$, $a=5$ → $M=3$ → $N=2^5 \\times 3=96$<br>Case2: $\\tau_{\\text{奇}}=5$, $a=2$ → $M=3^4=81$ → $N=324$<br>最小:<strong>96</strong>'
},
{
question: '对于小于 $50$ 的正整数 $N$,$\\tau_{\\text{偶}}(N) - \\tau_{\\text{奇}}(N)$ 的差值最大是多少?',
answer: '6',
hint: '差值 = (a-1)×τ奇(N)',
explanation: '差值 $D = (a-1) \\times \\tau_{\\text{奇}}(N)$<br>$a=4$: $N=16M<50$ → $M=3$ → $D=(4-1) \\times 2 = <strong>6</strong>$ (N=48)<br>$a=5$: $M=1$ → $D=4$<br>最大差值:<strong>6</strong>'
},
{
question: '一个正整数 $N$ 恰有 $3$ 个偶数约数,求所有可能的 $N$ 值的和。',
answer: '26',
hint: 'a×τ奇(N)=3',
explanation: '$a \\times \\tau_{\\text{奇}}(N)=3$<br>Case1: $a=3$, $\\tau_{\\text{奇}}=1$ → $M=1$ → $N=8$<br>Case2: $a=1$, $\\tau_{\\text{奇}}=3$ → $M=p^2=9$ → $N=18$<br>和:$8+18=<strong>26</strong>$'
},
{
question: '设 $N=20!$,求 $N$ 有多少个奇数约数?',
answer: '2160',
hint: '计算奇质因数的指数',
explanation: '奇质因数:3, 5, 7, 11, 13, 17, 19<br>$e_3=8$, $e_5=4$, $e_7=2$, $e_{11}=e_{13}=e_{17}=e_{19}=1$<br>$\\tau_{\\text{奇}} = 9 \\times 5 \\times 3 \\times 2^4 = <strong>2160</strong>$'
},
{
question: '已知 $N=2^a \\times 3^b$,$\\tau_{\\text{奇}}(N)=5$ 且 $\\tau(N)=20$,求 $N$。',
answer: '648',
hint: 'τ奇(N)=b+1=5',
explanation: '$b+1=5$ → $b=4$<br>$\\tau_{\\text{偶}}(N) = 20-5 = 15$<br>$a = 15/5 = 3$<br>$N = 2^3 \\times 3^4 = 8 \\times 81 = <strong>648</strong>$'
},
{
question: '正整数 $N$ 是完全平方数,且恰有 $10$ 个偶数约数,求 $N$ 的最小值。',
answer: '324',
hint: 'a必须是偶数,τ奇必须是奇数',
explanation: '$a \\times \\tau_{\\text{奇}}(N)=10$<br>$\\tau_{\\text{奇}}$ 必须是奇数 → 1 或 5<br>Case1: $\\tau_{\\text{奇}}=1$, $a=10$ → $N=2^{10}=1024$<br>Case2: $\\tau_{\\text{奇}}=5$, $a=2$ → $M=3^4=81$ → $N=4 \\times 81=<strong>324</strong>$'
},
{
question: '如果 $N$ 恰有 $12$ 个奇数约数和 $12$ 个偶数约数,求 $2$ 的指数 $a$。',
answer: '1',
hint: 'a × 12 = 12',
explanation: '$\\tau_{\\text{偶}}(N) = a \\times \\tau_{\\text{奇}}(N)$<br>$12 = a \\times 12$<br>$a = <strong>1</strong>$<br>($N$ 是2的倍数但不是4的倍数)'
},
{
question: '求满足 $\\tau_{\\text{偶}}(N) > 10$ 且 $\\tau_{\\text{奇}}(N)=1$ 的最小正整数 $N$。',
answer: '2048',
hint: 'τ奇(N)=1 → M=1',
explanation: '$\\tau_{\\text{奇}}(N)=1$ → $M=1$ → $N=2^a$<br>$\\tau_{\\text{偶}}(N) = a > 10$<br>最小整数 $a=11$<br>$N = 2^{11} = <strong>2048</strong>$'
},
{
question: '如果 $N=p^k$($p$ 为奇素数,$k \\ge 1$),那么 $\\tau_{\\text{偶}}(N) + \\tau_{\\text{奇}}(N)$ 等于多少(用k表示)?',
answer: 'k+1',
hint: 'N是奇数,τ偶(N)=0',
explanation: '$N$ 是奇数 → $a=0$ → $\\tau_{\\text{偶}}(N)=0$<br>$\\tau_{\\text{奇}}(N) = \\tau(N) = k+1$<br>$\\tau_{\\text{偶}}(N) + \\tau_{\\text{奇}}(N) = 0 + (k+1) = <strong>k+1</strong>$'
}
]
}
},
methods: {
// 语音播报
speak(text) {
if (window.speechSynthesis) window.speechSynthesis.cancel();
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
let audio = document.getElementById('tts-audio');
if (!audio) {
audio = document.createElement('audio'); audio.id = 'tts-audio'; audio.style.display = 'none';
document.body.appendChild(audio);
}
const url = `https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/tts.php?text=${encodeURIComponent(text)}&t=${Date.now()}`;
audio.src = url;
audio.play().catch(e => { if(window.WeixinJSBridge) window.WeixinJSBridge.invoke('getNetworkType',{},()=>audio.play()); });
} else {
if (window.speechSynthesis) {
const u = new SpeechSynthesisUtterance(text); u.lang = 'zh-CN'; u.rate = 0.9;
window.speechSynthesis.speak(u);
}
}
},
speakIntro() {
this.speak('为什么要学习奇数约数和偶数约数。我们已经知道如何求一个数的所有约数个数,现在要更精细地研究,这些约数中有多少个是奇数,有多少个是偶数。核心技巧是,把素因数分解式中的2单独提取出来,写成N等于2的a次方乘以M的形式,其中M是奇数部分,所有素因数大于等于3。这样就能方便地区分奇偶约数。');
},
speakOdd() {
this.speak('奇数约数的个数公式。一个数是奇数,意味着它的素因数分解中绝对不能出现因子2。所以奇数约数只能由M的素因数组成。N的所有奇数约数,实际上就是M的所有约数。因此,奇数约数个数等于M的约数个数。在计算时,只需要把2的幂次去掉,用奇数部分M的指数来计算。');
},
speakEven() {
this.speak('偶数约数的个数公式。一个数是偶数,意味着它至少含有一个因子2。有两种方法计算。方法一是减法,用总约数个数减去奇数约数个数。方法二是直接计算。偶数约数的结构是2的i次方乘以一个奇数,其中i从1到a,有a种选择,奇数部分有M的约数个数种选择。根据乘法原理,偶数约数个数等于a乘以M的约数个数。');
},
speakExample(index) {
const voice = this.classicExamples[index].voice;
if (voice) {
this.speak(voice);
}
},
// 页面切换
switchPage(page) {
if (window.speechSynthesis) window.speechSynthesis.cancel();
this.currentPage = page;
window.scrollTo(0, 0);
this.$nextTick(() => this.renderMath());
},
// 渲染数学公式
renderMath() {
if (typeof renderMathInElement !== 'undefined') {
setTimeout(() => {
renderMathInElement(document.body, {
delimiters: [
{ left: '$$', right: '$$', display: true },
{ left: '$', right: '$', display: false }
],
throwOnError: false
});
}, 100);
}
},
// 引入动画
animateIntro() {
const container = document.getElementById('intro-demo');
container.innerHTML = '';
// 72的所有约数
const allDivisors = [1, 2, 3, 4, 6, 8, 9, 12, 18, 24, 36, 72];
const oddDivisors = [1, 3, 9];
const evenDivisors = [2, 4, 6, 8, 12, 18, 24, 36, 72];
// 标题
const title = document.createElement('div');
title.style.cssText = 'color: white; font-size: 16px; font-weight: bold; margin-bottom: 20px;';
title.textContent = '72 = 2³ × 3²';
container.appendChild(title);
// 创建分类容器
const splitDiv = document.createElement('div');
splitDiv.className = 'split-container';
container.appendChild(splitDiv);
// 奇数约数区域
const oddSection = document.createElement('div');
oddSection.className = 'split-section';
const oddTitle = document.createElement('div');
oddTitle.className = 'split-title title-odd';
oddTitle.textContent = '奇数约数 (3个)';
oddSection.appendChild(oddTitle);
const oddGrid = document.createElement('div');
oddGrid.className = 'divisor-grid';
oddGrid.style.flexDirection = 'column';
oddDivisors.forEach((d, i) => {
const box = document.createElement('div');
box.className = 'divisor-box divisor-odd';
box.textContent = d;
oddGrid.appendChild(box);
gsap.fromTo(box, { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.4, delay: i * 0.3 });
});
oddSection.appendChild(oddGrid);
splitDiv.appendChild(oddSection);
// 偶数约数区域
const evenSection = document.createElement('div');
evenSection.className = 'split-section';
const evenTitle = document.createElement('div');
evenTitle.className = 'split-title title-even';
evenTitle.textContent = '偶数约数 (9个)';
evenSection.appendChild(evenTitle);
const evenGrid = document.createElement('div');
evenGrid.className = 'divisor-grid';
evenGrid.style.flexDirection = 'column';
evenGrid.style.maxHeight = '250px';
evenGrid.style.overflow = 'auto';
evenDivisors.forEach((d, i) => {
const box = document.createElement('div');
box.className = 'divisor-box divisor-even';
box.textContent = d;
evenGrid.appendChild(box);
gsap.fromTo(box, { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.3, delay: 1 + i * 0.15 });
});
evenSection.appendChild(evenGrid);
splitDiv.appendChild(evenSection);
document.getElementById('intro-text').textContent = '72共有12个约数:3个奇数,9个偶数';
},
// 奇数约数动画
animateOdd() {
const container = document.getElementById('odd-demo');
container.innerHTML = '';
const steps = [
{ eq: '$720 = 2^4 \\times 3^2 \\times 5^1$', exp: '素因数分解' },
{ eq: '提取奇数部分:$M = 3^2 \\times 5^1$', exp: '去掉2⁴' },
{ eq: '$\\tau_{\\text{奇}}(720) = \\tau(M)$', exp: '套用公式' },
{ eq: '$= \\tau(3^2 \\times 5^1)$', exp: 'M的约数个数' },
{ eq: '$= (2+1)(1+1)$', exp: '计算各指数+1' },
{ eq: '$= 3 \\times 2 = $ <span class="calc-highlight">$6$</span>', exp: '最终答案' }
];
steps.forEach((step, i) => {
const div = document.createElement('div');
div.className = 'calc-step';
div.innerHTML = `
<div class="calc-equation">${step.eq}</div>
<div class="calc-explanation">${step.exp}</div>
`;
container.appendChild(div);
gsap.to(div, {
opacity: 1,
duration: 0.5,
delay: i * 0.8,
onStart: () => {
div.classList.add('active');
document.getElementById('odd-text').textContent = `步骤${i + 1}:${step.exp}`;
}
});
});
setTimeout(() => this.renderMath(), 100);
},
// 偶数约数动画
animateEven() {
const container = document.getElementById('even-demo');
container.innerHTML = '';
const steps = [
{ eq: '$720 = 2^4 \\times 3^2 \\times 5^1$', exp: '素因数分解' },
{ eq: '$a = 4$(2的指数)', exp: '提取a' },
{ eq: '$\\tau_{\\text{奇}}(720) = 6$', exp: '已知奇数约数' },
{ eq: '$\\tau_{\\text{偶}}(720) = a \\times \\tau_{\\text{奇}}(720)$', exp: '套用公式' },
{ eq: '$= 4 \\times 6$', exp: '代入数值' },
{ eq: '<span class="calc-highlight">$= 24$</span>', exp: '最终答案' }
];
steps.forEach((step, i) => {
const div = document.createElement('div');
div.className = 'calc-step';
div.innerHTML = `
<div class="calc-equation">${step.eq}</div>
<div class="calc-explanation">${step.exp}</div>
`;
container.appendChild(div);
gsap.to(div, {
opacity: 1,
duration: 0.5,
delay: i * 0.8,
onStart: () => {
div.classList.add('active');
document.getElementById('even-text').textContent = `步骤${i + 1}:${step.exp}`;
}
});
});
setTimeout(() => this.renderMath(), 100);
},
// 例题切换
switchExample(index) {
this.exampleIndex = index;
this.$nextTick(() => this.renderMath());
},
nextExampleStep(index) {
if (this.exampleSteps[index] < this.classicExamples[index].steps.length - 1) {
this.exampleSteps[index]++;
this.$nextTick(() => this.renderMath());
}
},
prevExampleStep(index) {
if (this.exampleSteps[index] > 0) {
this.exampleSteps[index]--;
}
},
resetExampleStep(index) {
this.exampleSteps[index] = 0;
},
// 练习题
checkPracticeAnswer() {
if (this.practiceAnswered) return;
const correctAnswer = this.practiceQuestions[this.currentPracticeIndex].answer.toLowerCase().trim();
const userAnswer = this.userAnswer.toLowerCase().trim().replace(/\s+/g, '');
const correct = userAnswer === correctAnswer;
this.practiceAnswered = true;
this.isPracticeCorrect = correct;
if (correct) {
this.practiceScore += 10;
}
this.$nextTick(() => this.renderMath());
},
nextPractice() {
if (this.currentPracticeIndex < 9) {
this.currentPracticeIndex++;
this.practiceAnswered = false;
this.userAnswer = '';
this.$nextTick(() => this.renderMath());
} else {
this.practiceDone = true;
}
},
// 杯赛真题
checkOlympiadAnswer() {
if (this.olympiadAnswered) return;
const correctAnswer = this.olympiadQuestions[this.currentOlympiadIndex].answer.toLowerCase().trim();
const userAnswer = this.userOlympiadAnswer.toLowerCase().trim().replace(/\s+/g, '');
const correct = userAnswer === correctAnswer;
this.olympiadAnswered = true;
this.isOlympiadCorrect = correct;
if (correct) {
this.olympiadScore += 10;
}
this.$nextTick(() => this.renderMath());
},
nextOlympiad() {
if (this.currentOlympiadIndex < 9) {
this.currentOlympiadIndex++;
this.olympiadAnswered = false;
this.userOlympiadAnswer = '';
this.$nextTick(() => this.renderMath());
} else {
this.olympiadDone = true;
}
}
},
mounted() {
this.renderMath();
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 AI 生成。
登录后可复制完整代码