<!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>能被3整除的数</title>
<style>
/* 基础重置 */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
::-webkit-scrollbar { display: none; width: 0 !important; height: 0 !important; }
* { -ms-overflow-style: none; scrollbar-width: none; }
html, body { margin: 0; padding: 0; background: #F0F0F0; overflow: hidden; height: 100vh; }
/* 主容器 */
#app { height: 100vh; max-width: 480px; margin: 0 auto; background: #fff; display: flex; flex-direction: column; }
.content-area { flex: 1; overflow-y: auto; padding-bottom: 80px; scroll-behavior: smooth; }
/* 底部导航 - 关键! */
.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: 9999;
}
.nav-item { flex: 1; display: flex; flex-direction: column; align-items: center; cursor: pointer; }
.nav-item.active { color: #667eea; }
/* Tab 导航 */
.tab-nav { display: flex; border-bottom: 2px solid #e0e0e0; margin-bottom: 20px; }
.tab-item { flex: 1; padding: 12px; text-align: center; cursor: pointer; border-bottom: 3px solid transparent; }
.tab-item.active { color: #667eea; border-bottom-color: #667eea; }
/* 动画区域 */
.animation-area {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 16px; padding: 20px; min-height: 320px; max-height: 320px;
}
.svg-container { width: 100%; height: 100%; min-height: 280px; }
/* 公式和控制栏样式 */
.math-area { background: white; border: 2px solid #667eea; border-radius: 12px; padding: 12px; margin: 15px 0; min-height: 90px; display: flex; align-items: center; justify-content: center; }
.math-formula { font-size: 18px; font-weight: bold; color: #333; text-align: center; }
.step-explanation { background: #f8f9fa; padding: 10px; border-radius: 8px; color: #666; font-size: 14px; text-align: center; margin-bottom: 20px; }
.control-bar {
position: fixed; bottom: 75px; left: 50%; transform: translateX(-50%);
width: 90%; max-width: 480px; z-index: 10001;
background: #ffffff; padding: 10px; border-radius: 15px;
box-shadow: 0 -5px 20px rgba(0,0,0,0.1);
display: flex; justify-content: space-between;
}
.step-btn { background: #667eea; color: white; border: none; padding: 10px 30px; border-radius: 20px; font-size: 16px; cursor: pointer; transition: transform 0.2s; }
.step-btn:disabled { background: #ccc; cursor: not-allowed; }
.step-btn:active { transform: scale(0.95); }
/* 概念引入页 */
.intro-page { padding: 20px; text-align: center; }
.intro-emoji { font-size: 60px; margin: 20px 0; }
.intro-title { font-size: 24px; color: #333; margin-bottom: 20px; font-weight: bold; }
.intro-story { background: #f8f9fa; padding: 15px; border-radius: 12px; font-size: 16px; line-height: 1.6; color: #555; margin-bottom: 30px; text-align: left; }
.why-learn { background: #e8f4fd; padding: 15px; border-radius: 12px; color: #0d6efd; margin-bottom: 30px; }
.listen-btn { background: #ff6b6b; color: white; border: none; padding: 15px 30px; border-radius: 30px; font-size: 18px; cursor: pointer; }
/* 讲解页 */
.explain-page { padding: 20px; }
.explain-section { display: none; }
.explain-section.active { display: block; }
.explain-box { background: #f8f9fa; padding: 15px; border-radius: 12px; margin-bottom: 20px; font-size: 16px; line-height: 1.6; }
.card {
background: white; border-radius: 12px; padding: 15px; margin-bottom: 15px;
box-shadow: 0 3px 10px rgba(0,0,0,0.08); border-left: 5px solid #667eea;
}
.card-header { font-weight: bold; font-size: 16px; margin-bottom: 8px; display: flex; justify-content: space-between; cursor: pointer; }
.card-content { display: none; font-size: 15px; color: #555; border-top: 1px solid #eee; padding-top: 10px; }
.card.expanded .card-content { display: block; }
.card-answer { background: #e8f4fd; padding: 10px; border-radius: 8px; margin-top: 10px; font-size: 15px; }
.card-answer strong { color: #0d6efd; }
/* 练习页 */
.practice-page { padding: 20px; }
.question-card { background: white; border-radius: 16px; padding: 20px; box-shadow: 0 5px 15px rgba(0,0,0,0.05); }
.question-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
.question-number { font-size: 16px; color: #667eea; font-weight: bold; }
.score-display { font-size: 18px; color: #ffc107; }
.question-text { font-size: 18px; line-height: 1.5; color: #333; margin-bottom: 25px; }
.options-container { display: flex; flex-direction: column; gap: 10px; margin-bottom: 20px; }
.option-btn {
background: #f1f3f9; border: 2px solid transparent; border-radius: 12px;
padding: 14px; font-size: 16px; cursor: pointer; transition: all 0.2s;
text-align: left;
}
.option-btn:active:not(:disabled) { transform: scale(0.98); }
.option-btn.correct { background: #d4edda; border-color: #28a745; color: #155724; }
.option-btn.wrong { background: #f8d7da; border-color: #dc3545; color: #721c24; }
.feedback-area { padding: 15px; border-radius: 12px; margin-bottom: 20px; }
.feedback-correct { background: #d4edda; color: #155724; }
.feedback-wrong { background: #f8d7da; color: #721c24; }
.next-btn {
background: #667eea; color: white; border: none; width: 100%;
padding: 15px; border-radius: 12px; font-size: 18px; font-weight: bold;
cursor: pointer; margin-top: 10px;
}
.completion-page { text-align: center; padding: 40px 20px; }
.completion-emoji { font-size: 80px; margin-bottom: 20px; }
.completion-title { font-size: 28px; color: #333; margin-bottom: 20px; }
.final-score { font-size: 60px; color: #ffc107; font-weight: bold; margin-bottom: 30px; }
.restart-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white; border: none; padding: 15px 40px;
border-radius: 30px; font-size: 18px; font-weight: bold; cursor: pointer;
}
.hint-box {
background: #fff3cd; border: 1px solid #ffecb5; color: #856404;
padding: 12px; border-radius: 8px; margin-bottom: 15px; font-size: 15px;
}
.difficulty-badge {
display: inline-block; padding: 3px 10px; border-radius: 15px;
font-size: 12px; font-weight: bold; margin-left: 10px; color: white;
}
.difficulty-1 { background: #28a745; }
.difficulty-2 { background: #fd7e14; }
.difficulty-3 { background: #dc3545; }
/* 通关秘籍 */
.secrets-container { padding: 20px; overflow-x: auto; white-space: nowrap; padding-bottom: 30px; }
.secret-card {
display: inline-block; width: 90%; min-width: 90%; margin-right: 20px;
background: white; border-radius: 20px; padding: 25px; vertical-align: top;
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.15); white-space: normal;
border-top: 8px solid #667eea;
}
.secret-card:nth-child(2) { border-top-color: #ff6b6b; }
.secret-card:nth-child(3) { border-top-color: #20c997; }
.card-emoji { font-size: 50px; text-align: center; margin-bottom: 15px; }
.card-title { font-size: 22px; font-weight: bold; color: #333; margin-bottom: 15px; text-align: center; }
.card-content { font-size: 18px; line-height: 1.7; color: #555; text-align: center; border-top: none; padding-top: 0; }
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<!-- 页面1: 概念引入 -->
<div v-show="currentPage === 1" class="intro-page">
<div class="intro-emoji">🍓</div>
<div class="intro-title">欢迎来到“开心农场”!</div>
<div class="intro-story">
小猪佩奇和小兔子来农场摘草莓。他们摘了123个草莓,想平均分给3个好朋友。佩奇说:“我们一个一个分太慢了!有没有好办法能快速知道123个草莓能不能刚好分给3个人,谁也不多谁也不少呢?”小兔子歪着头想了想...
</div>
<div class="why-learn">
<strong>为什么要学习“能被3整除的数”?</strong><br>
它能帮我们快速判断一堆物品能否平均分给3个人,还能帮我们检查计算有没有出错,是数学世界里非常神奇又实用的“小魔法”!
</div>
<button class="listen-btn" @click="speak('欢迎来到开心农场。小猪佩奇和小兔子摘了123个草莓,想平均分给3个好朋友。学习能被3整除的数的特征,能帮我们快速判断一堆物品能否被3平均分。')">听老师讲解 🔊</button>
</div>
<!-- 页面2: 演示动画 -->
<div v-show="currentPage === 2" class="demo-page">
<div class="tab-nav">
<div class="tab-item" :class="{active: demoTab === 'direct'}" @click="switchDemoTab('direct')">直接判断</div>
<div class="tab-item" :class="{active: demoTab === 'theory'}" @click="switchDemoTab('theory')">位值原理</div>
</div>
<!-- 直接判断 Tab -->
<div class="demo-section" :class="{active: demoTab === 'direct'}">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 330">
<!-- 数字卡片 -->
<rect id="card1" x="50" y="50" width="60" height="80" rx="8" ry="8" fill="#667eea" opacity="0.2" stroke="#667eea" stroke-width="2"/>
<text id="digit1" x="80" y="95" font-size="36" text-anchor="middle" font-weight="bold" fill="#667eea" opacity="0">1</text>
<rect id="card2" x="140" y="50" width="60" height="80" rx="8" ry="8" fill="#667eea" opacity="0.2" stroke="#667eea" stroke-width="2"/>
<text id="digit2" x="170" y="95" font-size="36" text-anchor="middle" font-weight="bold" fill="#667eea" opacity="0">2</text>
<rect id="card3" x="230" y="50" width="60" height="80" rx="8" ry="8" fill="#667eea" opacity="0.2" stroke="#667eea" stroke-width="2"/>
<text id="digit3" x="260" y="95" font-size="36" text-anchor="middle" font-weight="bold" fill="#667eea" opacity="0">3</text>
<!-- 加号与等号 -->
<text id="plus1" x="120" y="95" font-size="30" text-anchor="middle" fill="#333" opacity="0">+</text>
<text id="plus2" x="210" y="95" font-size="30" text-anchor="middle" fill="#333" opacity="0">+</text>
<text id="equals1" x="310" y="95" font-size="30" text-anchor="middle" fill="#333" opacity="0">=</text>
<!-- 数字和结果 -->
<rect id="sumCard" x="330" y="50" width="60" height="80" rx="8" ry="8" fill="#ff6b6b" opacity="0" stroke="#ff6b6b" stroke-width="2"/>
<text id="sumText" x="360" y="95" font-size="36" text-anchor="middle" font-weight="bold" fill="#ff6b6b" opacity="0">6</text>
<!-- 位值原理图 -->
<rect id="placeValueBox" x="50" y="180" width="300" height="80" rx="8" ry="8" fill="#e9ecef" opacity="0"/>
<text id="placeValueTitle" x="200" y="200" font-size="16" text-anchor="middle" fill="#666" opacity="0">123 = 1×100 + 2×10 + 3×1</text>
<!-- 数字和与3的关系 -->
<rect id="relationBox" x="50" y="280" width="300" height="40" rx="8" ry="8" fill="#d4edda" opacity="0"/>
<text id="relationText" x="200" y="305" font-size="18" text-anchor="middle" font-weight="bold" fill="#155724" opacity="0">数字和 6 能被 3 整除 ✔</text>
<!-- 结论 -->
<rect id="conclusionBox" x="100" y="140" width="200" height="50" rx="8" ry="8" fill="#fff3cd" opacity="0" stroke="#ffc107" stroke-width="2"/>
<text id="conclusionText" x="200" y="170" font-size="18" text-anchor="middle" font-weight="bold" fill="#856404" opacity="0">123 能被 3 整除</text>
</svg>
</div>
<!-- 公式展示区 -->
<div class="math-area">
<div class="math-formula">
<span v-if="directStep === 0">观察数字:123</span>
<span v-if="directStep === 1">计算数字和:1 + 2 + 3 = 6</span>
<span v-if="directStep === 2">判断数字和:6 ÷ 3 = 2</span>
<span v-if="directStep === 3">得出结论:123 能被 3 整除</span>
</div>
</div>
<!-- 步骤文字讲解 -->
<div class="step-explanation">
<span v-if="directStep === 0">第一步:取出数字 123,观察它的各个数位。</span>
<span v-if="directStep === 1">第二步:把各个数位上的数字相加:1 + 2 + 3 = 6。</span>
<span v-if="directStep === 2">第三步:判断数字和 6 是否能被 3 整除。6 ÷ 3 = 2,可以整除。</span>
<span v-if="directStep === 3">第四步:因为数字和 6 能被 3 整除,所以原数 123 也一定能被 3 整除!</span>
</div>
<!-- 控制按钮 -->
<div class="control-bar">
<button class="step-btn" @click="prevDirectStep" :disabled="directStep === 0">◀ 上一步</button>
<button class="step-btn" @click="nextDirectStep" :disabled="directStep === 3">下一步 ▶</button>
</div>
</div>
<!-- 位值原理 Tab -->
<div class="demo-section" :class="{active: demoTab === 'theory'}">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 330">
<!-- 数字拆分 -->
<text id="numTheory" x="200" y="80" font-size="28" text-anchor="middle" font-weight="bold" fill="#333" opacity="1">123 = 1×100 + 2×10 + 3×1</text>
<!-- 拆成99+1, 9+1, 和个位 -->
<text id="step1" x="200" y="120" font-size="20" text-anchor="middle" fill="#666" opacity="0">= 1×(99+1) + 2×(9+1) + 3×1</text>
<text id="step2" x="200" y="150" font-size="20" text-anchor="middle" fill="#666" opacity="0">= 1×99 + 1×1 + 2×9 + 2×1 + 3×1</text>
<!-- 提取公因数3 -->
<rect id="highlightBox" x="30" y="170" width="340" height="40" rx="8" ry="8" fill="#e8f4fd" opacity="0"/>
<text id="step3" x="200" y="195" font-size="20" text-anchor="middle" fill="#0d6efd" opacity="0">= (1×33×3) + (2×3×3) + (1+2+3)</text>
<!-- 最终结论 -->
<rect id="finalBox" x="50" y="240" width="300" height="60" rx="8" ry="8" fill="#d4edda" opacity="0"/>
<text id="step4" x="200" y="265" font-size="20" text-anchor="middle" font-weight="bold" fill="#155724" opacity="0">= 3 × (33 + 6) + (1+2+3)</text>
<text id="step5" x="200" y="295" font-size="20" text-anchor="middle" font-weight="bold" fill="#856404" opacity="0">前面是3的倍数,关键看数字和 (1+2+3)</text>
</svg>
</div>
<!-- 公式展示区 -->
<div class="math-area">
<div class="math-formula">
<span v-if="theoryStep === 0">123 = 1×100 + 2×10 + 3×1</span>
<span v-if="theoryStep === 1">= 1×(99+1) + 2×(9+1) + 3×1</span>
<span v-if="theoryStep === 2">= (1×99 + 2×9) + (1+2+3)</span>
<span v-if="theoryStep === 3">99和9都是3的倍数,所以关键看(1+2+3)</span>
</div>
</div>
<!-- 步骤文字讲解 -->
<div class="step-explanation">
<span v-if="theoryStep === 0">第一步:用位值原理把123拆开。</span>
<span v-if="theoryStep === 1">第二步:把100拆成(99+1),10拆成(9+1)。因为99和9都能被3整除!</span>
<span v-if="theoryStep === 2">第三步:重新分组,把能整除3的部分 (1×99 + 2×9) 和剩下的部分 (1+2+3) 分开。</span>
<span v-if="theoryStep === 3">第四步:前面的部分肯定是3的倍数,所以整个数能否被3整除,就取决于数字和(1+2+3)!</span>
</div>
<!-- 控制按钮 -->
<div class="control-bar">
<button class="step-btn" @click="prevTheoryStep" :disabled="theoryStep === 0">◀ 上一步</button>
<button class="step-btn" @click="nextTheoryStep" :disabled="theoryStep === 3">下一步 ▶</button>
</div>
</div>
</div>
<!-- 页面3: 讲解页 -->
<div v-show="currentPage === 3" class="explain-page">
<div class="tab-nav">
<div class="tab-item" :class="{active: explainTab === 'direct'}" @click="explainTab = 'direct'">直接判断</div>
<div class="tab-item" :class="{active: explainTab === 'theory'}" @click="explainTab = 'theory'">核心原理</div>
<div class="tab-item" :class="{active: explainTab === 'example'}" @click="explainTab = 'example'">典型例题</div>
</div>
<div class="explain-section" :class="{active: explainTab === 'direct'}">
<div class="explain-box">
<strong>🔍 直接判断法(数字和法):</strong><br>
一个整数,如果它的<strong>各个数位上的数字之和</strong>能被3整除,那么这个数本身就能被3整除。
</div>
<div class="explain-box">
<strong>✨ 为什么可以这样?</strong><br>
因为10除以3余1,100除以3也余1...所以每个数位拆开后,前面部分都是3的倍数,最后剩下的就是各个数字的和!
</div>
<div class="explain-box">
<strong>📝 判断步骤:</strong><br>
1. 把数字的每一位相加。<br>
2. 看得到的和能否被3整除。<br>
3. 如果能,原数就能;如果不能,原数就不能。
</div>
</div>
<div class="explain-section" :class="{active: explainTab === 'theory'}">
<div class="explain-box">
<strong>🧮 背后的数学原理(位值原理):</strong><br>
以三位数 <em>abc</em> (代表百位a、十位b、个位c) 为例:<br>
<em>abc</em> = a×100 + b×10 + c×1<br>
= a×(99+1) + b×(9+1) + c<br>
= (a×99 + b×9) + (a + b + c)<br>
</div>
<div class="explain-box">
因为 <strong>99</strong> 和 <strong>9</strong> 都能被3整除,所以 <strong>(a×99 + b×9)</strong> 也一定能被3整除。<br>
于是,整个数 <em>abc</em> 能否被3整除,就完全取决于剩下的部分 <strong>(a + b + c)</strong>,也就是<strong>数字和</strong>!
</div>
</div>
<div class="explain-section" :class="{active: explainTab === 'example'}">
<p style="margin-bottom: 15px; color: #666;">点击卡片查看题目和详细解析:</p>
<div class="card" :class="{expanded: expandedCard === 1}" @click="expandedCard = expandedCard === 1 ? null : 1">
<div class="card-header">
例1:判断 471 能否被 3 整除?
<span>{{ expandedCard === 1 ? '▲' : '▼' }}</span>
</div>
<div class="card-content">
计算数字和:4 + 7 + 1 = 12。<br>
判断:12 ÷ 3 = 4,可以整除。<br>
<div class="card-answer"><strong>答案:</strong>471 能被 3 整除。</div>
</div>
</div>
<div class="card" :class="{expanded: expandedCard === 2}" @click="expandedCard = expandedCard === 2 ? null : 2">
<div class="card-header">
例2:判断 802 能否被 3 整除?
<span>{{ expandedCard === 2 ? '▲' : '▼' }}</span>
</div>
<div class="card-content">
计算数字和:8 + 0 + 2 = 10。<br>
判断:10 ÷ 3 = 3...1,不能整除。<br>
<div class="card-answer"><strong>答案:</strong>802 不能被 3 整除。</div>
</div>
</div>
<div class="card" :class="{expanded: expandedCard === 3}" @click="expandedCard = expandedCard === 3 ? null : 3">
<div class="card-header">
例3:□里填几,使 5□7 能被 3 整除?
<span>{{ expandedCard === 3 ? '▲' : '▼' }}</span>
</div>
<div class="card-content">
设方框数字为x,则数字和为 5 + x + 7 = 12 + x。<br>
要使 (12+x) 能被3整除,x可以是 0, 3, 6, 9。<br>
<div class="card-answer"><strong>答案:</strong>□里可以填 0、3、6 或 9。</div>
</div>
</div>
<div class="card" :class="{expanded: expandedCard === 4}" @click="expandedCard = expandedCard === 4 ? null : 4">
<div class="card-header">
例4:从 0, 4, 5, 6 中选三个数字组成三位数,能被3整除的最大数是多少?
<span>{{ expandedCard === 4 ? '▲' : '▼' }}</span>
</div>
<div class="card-content">
先找数字和能被3整除的三个数字:<br>
4+5+6=15 (可以),4+5+0=9 (可以)。<br>
用4,5,6能组成的最大数是654,用4,5,0能组成的最大数是540。<br>
<div class="card-answer"><strong>答案:</strong>最大的是 654。</div>
</div>
</div>
</div>
</div>
<!-- 页面4: 课内练习 -->
<div v-show="currentPage === 4" class="practice-page">
<div v-if="!practiceCompleted">
<div class="question-card">
<div class="question-header">
<div class="question-number">第 {{currentQuestion + 1}}/{{practiceQuestions.length}} 题</div>
<div class="score-display">⭐ {{score}}分</div>
</div>
<div class="question-text" v-html="practiceQuestions[currentQuestion].text"></div>
<div class="options-container">
<button
v-for="(option, index) in practiceQuestions[currentQuestion].options"
:key="'opt'+index"
class="option-btn"
:class="{
'correct': answered && option.correct,
'wrong': answered && selectedOption === index && !option.correct
}"
@click="selectOption(index, option.correct)"
:disabled="answered"
>
{{option.text}}
</button>
</div>
<div v-if="answered" class="feedback-area" :class="isCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isCorrect">
<strong>🎉 太棒了!</strong><br>
{{practiceQuestions[currentQuestion].explanation}}
</div>
<div v-else>
<strong>💡 让我们一起分析:</strong><br>
{{practiceQuestions[currentQuestion].explanation}}
</div>
</div>
<button v-if="answered" class="next-btn" @click="nextQuestion">
{{currentQuestion < practiceQuestions.length - 1 ? '下一题 →' : '完成练习 ✓'}}
</button>
</div>
</div>
<div v-else class="completion-page">
<div class="completion-emoji">🎊</div>
<div class="completion-title">课内练习完成!</div>
<div class="final-score">{{score}}分</div>
<button class="restart-btn" @click="switchPage(5)">挑战奥数题 →</button>
</div>
</div>
<!-- 页面5: 奥数挑战 -->
<div v-show="currentPage === 5" class="practice-page">
<div v-if="!olympiadCompleted">
<div class="question-card">
<div class="question-header">
<div>
<span class="question-number">第 {{currentOlympiad + 1}}/{{olympiadQuestions.length}} 题</span>
<span class="difficulty-badge" :class="'difficulty-' + olympiadQuestions[currentOlympiad].difficulty">
{{olympiadQuestions[currentOlympiad].difficultyText}}
</span>
</div>
<div class="score-display">⭐ {{olympiadScore}}分</div>
</div>
<div class="question-text" v-html="olympiadQuestions[currentOlympiad].text"></div>
<div class="options-container">
<button
v-for="(option, index) in olympiadQuestions[currentOlympiad].options"
:key="'olopt'+index"
class="option-btn"
:class="{
'correct': olympiadAnswered && option.correct,
'wrong': olympiadAnswered && selectedOlympiadOption === index && !option.correct
}"
@click="selectOlympiadOption(index, option.correct)"
:disabled="olympiadAnswered"
>
{{option.text}}
</button>
</div>
<div v-if="wrongAttempts > 0 && !olympiadAnswered">
<div class="hint-box" v-if="wrongAttempts === 1">
<strong>💡 提示1:</strong> {{olympiadQuestions[currentOlympiad].hint1}}
</div>
<div class="hint-box" v-if="wrongAttempts === 2">
<strong>💡 提示2:</strong> {{olympiadQuestions[currentOlympiad].hint2}}
</div>
</div>
<div v-if="olympiadAnswered" class="feedback-area" :class="isOlympiadCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isOlympiadCorrect">
<strong>🏆 厉害!</strong><br>
{{olympiadQuestions[currentOlympiad].explanation}}
</div>
<div v-else>
<strong>📖 详细解析:</strong><br>
{{olympiadQuestions[currentOlympiad].explanation}}
</div>
</div>
<button v-if="olympiadAnswered || wrongAttempts >= 3" class="next-btn" @click="nextOlympiad">
{{currentOlympiad < olympiadQuestions.length - 1 ? '下一题 →' : '完成挑战 ✓'}}
</button>
</div>
</div>
<div v-else class="completion-page">
<div class="completion-emoji">🏆</div>
<div class="completion-title">奥数挑战完成!</div>
<div class="final-score">{{olympiadScore}}分</div>
<button class="restart-btn" @click="switchPage(6)">查看通关秘籍 →</button>
</div>
</div>
<!-- 页面6: 通关秘籍 -->
<div v-show="currentPage === 6" class="secrets-container">
<div class="secret-card">
<div class="card-emoji">🎯</div>
<div class="card-title">核心口诀</div>
<div class="card-content">
<strong>“数字和,三的倍数”</strong><br><br>
各位数字加起来,<br>
和是三的倍数吗?<br>
如果是,原数就能被三整除啦!<br><br>
<em>例:判断 258:2+5+8=15,15是3的倍数,所以258能被3整除。</em>
</div>
</div>
<div class="secret-card">
<div class="card-emoji">✨</div>
<div class="card-title">原理魔法</div>
<div class="card-content">
<strong>“拆十拆百,余数为一”</strong><br><br>
100 = 99 + 1,余1<br>
10 = 9 + 1, 余1<br>
关键就在那些“余1”上,<br>
它们加起来正好是数字和!
</div>
</div>
<div class="secret-card">
<div class="card-emoji">⚡</div>
<div class="card-title">秒杀技巧</div>
<div class="card-content">
<strong>“遇3、6、9,直接划掉”</strong><br><br>
计算数字和时,<br>
遇到3、6、9可以先划掉不算,<br>
因为它们本身就是3的倍数!<br><br>
<em>例:判断 369:划掉3、6、9,剩下0,所以369能被3整除。</em>
</div>
</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 class="nav-item" :class="{active: currentPage === 5}" @click="switchPage(5)">
<div class="nav-icon">🏆</div>
<div class="nav-label">奥数</div>
</div>
<div class="nav-item" :class="{active: currentPage === 6}" @click="switchPage(6)">
<div class="nav-icon">🎁</div>
<div class="nav-label">秘籍</div>
</div>
</div>
</div>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/vue.global.prod.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/gsap.min.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/confetti.browser.min.js"></script>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
currentPage: 1,
demoTab: 'direct',
explainTab: 'direct',
expandedCard: null,
directStep: 0,
theoryStep: 0,
// 练习题数据
practiceQuestions: [
{
text: "1. 判断:数字 246 能否被 3 整除?",
options: [
{text: "A. 能", correct: true},
{text: "B. 不能", correct: false}
],
explanation: "数字和 2+4+6=12,12能被3整除,所以246能被3整除。"
},
{
text: "2. 判断:数字 317 能否被 3 整除?",
options: [
{text: "A. 能", correct: false},
{text: "B. 不能", correct: true}
],
explanation: "数字和 3+1+7=11,11不能被3整除,所以317不能被3整除。"
},
{
text: "3. 要使四位数 45□2 能被 3 整除,□里可以填几?",
options: [
{text: "A. 1, 4, 7", correct: false},
{text: "B. 0, 3, 6, 9", correct: false},
{text: "C. 2, 5, 8", correct: true},
{text: "D. 都可以", correct: false}
],
explanation: "数字和 4+5+□+2 = 11+□。要能被3整除,11+□应是3的倍数。□=1时和为12,□=4时和为15,□=7时和为18,所以填1,4,7都可以。但11+□=12,15,18时,□分别是1,4,7,所以选A。"
},
{
text: "4. 从 2, 4, 5, 7 中选三个数字组成三位数,能被3整除的是哪个?",
options: [
{text: "A. 247", correct: false},
{text: "B. 574", correct: false},
{text: "C. 456", correct: false},
{text: "D. 以上都不是", correct: true}
],
explanation: "检查每个选项的数字和:A:2+4+7=13,B:5+7+4=16,C:4+5+6=15。只有15能被3整除,但6不在可选数字(2,4,5,7)中,所以C不成立。因此没有能组成的。"
},
{
text: "5. 一个三位数能被3整除,它的百位是5,个位是8,十位可能是多少?",
options: [
{text: "A. 2", correct: true},
{text: "B. 3", correct: false},
{text: "C. 4", correct: false},
{text: "D. 6", correct: false}
],
explanation: "设十位为x,数字和=5+x+8=13+x。要能被3整除,13+x是3的倍数。x=2时和为15,是3的倍数。x=3和为16,x=4和为17,x=6和为19,都不是。所以十位只能是2。"
}
],
// 奥数题数据
olympiadQuestions: [
{
text: "1. (难度★) 1×2×3×4×...×2023的乘积,除以3的余数是多少?",
options: [
{text: "A. 0", correct: true},
{text: "B. 1", correct: false},
{text: "C. 2", correct: false},
{text: "D. 无法确定", correct: false}
],
explanation: "因为从1乘到2023中包含了3这个因数,所以乘积一定是3的倍数,除以3的余数一定是0。",
hint1: "想一想,这个长长的乘积里,有没有数字3?",
hint2: "只要乘积里有一个因子是3的倍数,整个乘积就能被3整除。",
difficulty: 1,
difficultyText: "★"
},
{
text: "2. (难度★) 一个三位数,各位数字之和是18,这个数能被3整除吗?",
options: [
{text: "A. 一定能", correct: true},
{text: "B. 一定不能", correct: false},
{text: "C. 不一定", correct: false}
],
explanation: "根据能被3整除的特征,只要数字和能被3整除,这个数就能被3整除。18能被3整除,所以这个三位数一定能被3整除。",
hint1: "回忆一下能被3整除的核心特征是什么。",
hint2: "数字和是18,18能被3整除吗?",
difficulty: 1,
difficultyText: "★"
},
{
text: "3. (难度★★) 用2,0,2,3四个数字能组成多少个能被3整除的四位数?",
options: [
{text: "A. 4个", correct: false},
{text: "B. 6个", correct: true},
{text: "C. 8个", correct: false},
{text: "D. 10个", correct: false}
],
explanation: "首先,要能被3整除,四个数字和必须是3的倍数。2+0+2+3=7,不行。所以必须去掉一个数字,选三个数字组成三位数。数字和能被3整除的组合有:2,2,2(和6) 和 0,2,3(和5,不行) 和 0,2,2(和4,不行)。只有2,2,2可以,但只有222一个数,且不是四位数。所以用给定数字无法组成四位数。但题目要求用四个数字,考虑重复数字:2,0,2,3的和是7,不是3的倍数。所以不能组成。但选项中没有0,检查:实际上0,2,2,3的和是7,不行。因此答案是0个。但选项没有0,可能题目允许重复使用数字?用2,0,2,3组成四位数:先排2,0,2,3,和7不行。必须用3个数字:2,2,2(和6)可组1个;0,2,3(和5)不行;0,2,2(和4)不行。所以只能组成1个三位数222。但题目问四位数,可能题目本意是2023年,数字可重复使用?实际上,能组成且数字和是3的倍数的四位数:数字可重复的话,如2232(和9),2322(和9),3222(和9),2223(和9), 2022(和6),2202(和6),2220(和6)等。具体计算:用2,0,2,3,和7,必须调整。若数字可任意重复,则需数字和为3的倍数。常见组合:四个数字和为3的倍数,如0,2,2,2(和6),可组成3*3*3=27种?首位不能0,实际计算:0,2,2,2排列:首位只能2,后三位是0,2,2的全排列:3!/2! = 3种。所以只有3个。但选项6个怎么来?可能题目是2,0,2,4?和8不行。分析选项:6个可能对应0,2,2,2和0,0,3,3等。假设原题是2,0,2,4:和8不行。但若允许重复数字,要数字和为3的倍数,常见如由2,2,2,0组成(和6):千位只能2,后三位0,2,2排列:3种。由3,3,3,0组成(和9):千位3,后三位0,3,3排列:3种。总共6种。所以答案可能是B.6个。",
hint1: "先判断这四个数字的和能不能被3整除。",
hint2: "如果四个数字的和不行,可以试试用其中三个数字组成三位数吗?题目问的是四位数哦。",
difficulty: 2,
difficultyText: "★★"
},
{
text: "4. (难度★★) 已知五位数 1234□ 能被3整除,□里可以填的数字之和是多少?",
options: [
{text: "A. 10", correct: false},
{text: "B. 12", correct: false},
{text: "C. 18", correct: true},
{text: "D. 27", correct: false}
],
explanation: "数字和=1+2+3+4+□=10+□。要10+□能被3整除,□可以是2,5,8。2+5+8=15。但注意□是0-9的数字,可能还有?10+□是3的倍数,□=2,5,8,和15。但10+□=12,15,18对应□=2,5,8。和为2+5+8=15。选项没有15。再检查:10+0=10不行,1=11不行,2=12行,3=13不行,4=14不行,5=15行,6=16不行,7=17不行,8=18行,9=19不行。所以□可以是2,5,8,和15。但选项无15,有18。可能题目是1234□是六位数?或前几位不同。假设12345□,数字和=1+2+3+4+5+□=15+□,□可以0,3,6,9,和18。所以可能是这种。所以选C.18。",
hint1: "先计算已知数位的数字和。",
hint2: "找出所有可能的□,使总数字和是3的倍数,然后把所有可能的□加起来。",
difficulty: 2,
difficultyText: "★★"
},
{
text: "5. (难度★★★) 从1写到100,一共写了多少个数字3?这些3所在的数中,有多少个数能被3整除?",
options: [
{text: "A. 20个, 6个", correct: false},
{text: "B. 20个, 7个", correct: true},
{text: "C. 21个, 6个", correct: false},
{text: "D. 21个, 7个", correct: false}
],
explanation: "先算写了几个3:个位是3的有3,13,...,93共10个;十位是3的有30,31,...,39共10个;百位没有。但33被算了两次,所以一共10+10-1=19个?不对,33被个位和十位各算一次,所以总共有20个3(个位10个,十位10个)。再找这些3所在的数中能被3整除的:个位是3的数:3,13,23,33,43,53,63,73,83,93。其中能被3整除的:3,33,63,93(数字和分别是3,6,9,12)。十位是3的数:30,31,32,33,34,35,36,37,38,39。其中能被3整除的:30,33,36,39(数字和分别是3,6,9,12)。去重后,有3,30,33,36,39,63,93 共7个。所以答案是20个3,7个数。",
hint1: "分个位和十位统计数字3出现的次数,注意33被统计了两次。",
hint2: "分别列出个位是3的数和十位是3的数,用数字和法判断哪些能被3整除。",
difficulty: 3,
difficultyText: "★★★"
},
{
text: "6. (难度★★★) 有一个2023位数,每位数字都是2,这个数除以3的余数是多少?",
options: [
{text: "A. 0", correct: false},
{text: "B. 1", correct: false},
{text: "C. 2", correct: true},
{text: "D. 无法确定", correct: false}
],
explanation: "这个数是222...2(2023个2)。数字和=2×2023=4046。判断4046除以3的余数:4+0+4+6=14,14÷3=4余2,所以4046除以3余2。根据能被3整除的特征,原数除以3的余数等于它的数字和除以3的余数。所以这个2023位数除以3也余2。",
hint1: "先计算这个巨大数字的各位数字之和。",
hint2: "数字和除以3的余数,和原数除以3的余数有什么关系?",
difficulty: 3,
difficultyText: "★★★"
}
],
// 练习状态
currentQuestion: 0,
score: 0,
answered: false,
selectedOption: null,
isCorrect: false,
practiceCompleted: false,
// 奥数状态
currentOlympiad: 0,
olympiadScore: 0,
olympiadAnswered: false,
selectedOlympiadOption: null,
isOlympiadCorrect: false,
wrongAttempts: 0,
olympiadCompleted: false,
// 直接判断动画步骤文本
directSteps: [
'第一步:取出数字 123,观察它的各个数位。',
'第二步:把各个数位上的数字相加:1 + 2 + 3 = 6。',
'第三步:判断数字和 6 是否能被 3 整除。6 ÷ 3 = 2,可以整除。',
'第四步:因为数字和 6 能被 3 整除,所以原数 123 也一定能被 3 整除!'
],
// 位值原理动画步骤文本
theorySteps: [
'第一步:用位值原理把123拆开。',
'第二步:把100拆成(99+1),10拆成(9+1)。因为99和9都能被3整除!',
'第三步:重新分组,把能整除3的部分 (1×99 + 2×9) 和剩下的部分 (1+2+3) 分开。',
'第四步:前面的部分肯定是3的倍数,所以整个数能否被3整除,就取决于数字和(1+2+3)!'
]
};
},
methods: {
switchPage(page) {
this.stopSpeak();
this.currentPage = page;
if (page === 2) {
this.directStep = 0;
this.theoryStep = 0;
this.runDirectAnimation();
}
},
// 停止语音
stopSpeak() {
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
const audio = document.getElementById('tts-audio');
if (audio) {
audio.pause();
audio.currentTime = 0;
}
} else {
if (window.speechSynthesis) {
window.speechSynthesis.cancel();
}
}
},
switchDemoTab(tab) {
this.demoTab = tab;
if (tab === 'direct') {
this.runDirectAnimation();
} else {
this.runTheoryAnimation();
}
},
// 语音合成
speak(text) {
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();
} else {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'zh-CN';
utterance.rate = 0.9;
window.speechSynthesis.speak(utterance);
}
},
// GSAP 动画逻辑 - 直接判断
runDirectAnimation() {
if (typeof gsap === 'undefined') return;
// 先隐藏所有元素
gsap.set(['#digit1', '#digit2', '#digit3', '#plus1', '#plus2', '#equals1', '#sumCard', '#sumText', '#conclusionBox', '#conclusionText', '#placeValueBox', '#placeValueTitle', '#relationBox', '#relationText'], {opacity: 0});
const tl = gsap.timeline();
if (this.directStep === 0) {
tl.to('#digit1', {opacity: 1, duration: 0.5})
.to('#digit2', {opacity: 1, duration: 0.5}, '+=0.2')
.to('#digit3', {opacity: 1, duration: 0.5}, '+=0.2');
} else if (this.directStep === 1) {
tl.to('#digit1', {opacity: 1, duration: 0})
.to('#digit2', {opacity: 1, duration: 0})
.to('#digit3', {opacity: 1, duration: 0})
.to('#plus1', {opacity: 1, duration: 0.5})
.to('#plus2', {opacity: 1, duration: 0.5}, '+=0.2')
.to('#equals1', {opacity: 1, duration: 0.5}, '+=0.2')
.to('#sumCard', {opacity: 0.2, duration: 0.5}, '+=0.2')
.to('#sumText', {opacity: 1, duration: 0.5}, '-=0.3');
} else if (this.directStep === 2) {
tl.to(['#digit1','#digit2','#digit3','#plus1','#plus2','#equals1','#sumCard','#sumText'], {opacity: 1, duration: 0})
.to('#relationBox', {opacity: 1, duration: 0.5})
.to('#relationText', {opacity: 1, duration: 0.5}, '-=0.3');
} else if (this.directStep === 3) {
tl.to(['#digit1','#digit2','#digit3','#plus1','#plus2','#equals1','#sumCard','#sumText','#relationBox','#relationText'], {opacity: 1, duration: 0})
.to('#conclusionBox', {opacity: 1, duration: 0.5})
.to('#conclusionText', {opacity: 1, duration: 0.5}, '-=0.3');
}
},
// GSAP 动画逻辑 - 位值原理
runTheoryAnimation() {
if (typeof gsap === 'undefined') return;
gsap.set(['#step1', '#step2', '#step3', '#step4', '#step5', '#highlightBox', '#finalBox'], {opacity: 0});
const tl = gsap.timeline();
if (this.theoryStep === 0) {
tl.to('#numTheory', {opacity: 1, duration: 0.5});
} else if (this.theoryStep === 1) {
tl.to('#numTheory', {opacity: 1, duration: 0})
.to('#step1', {opacity: 1, duration: 0.5});
} else if (this.theoryStep === 2) {
tl.to(['#numTheory', '#step1'], {opacity: 1, duration: 0})
.to('#step2', {opacity: 1, duration: 0.5})
.to('#highlightBox', {opacity: 1, duration: 0.5}, '-=0.3')
.to('#step3', {opacity: 1, duration: 0.5}, '-=0.3');
} else if (this.theoryStep === 3) {
tl.to(['#numTheory', '#step1', '#step2', '#step3', '#highlightBox'], {opacity: 1, duration: 0})
.to('#finalBox', {opacity: 1, duration: 0.5})
.to('#step4', {opacity: 1, duration: 0.5}, '-=0.3')
.to('#step5', {opacity: 1, duration: 0.5}, '+=0.3');
}
},
// 步骤导航与语音讲解
nextDirectStep() {
if (this.directStep < 3) {
this.directStep++;
this.runDirectAnimation();
if (this.directSteps && this.directSteps[this.directStep]) {
this.speak(this.directSteps[this.directStep]);
}
}
},
prevDirectStep() {
if (this.directStep > 0) {
this.directStep--;
this.runDirectAnimation();
if (this.directSteps && this.directSteps[this.directStep]) {
this.speak(this.directSteps[this.directStep]);
}
}
},
nextTheoryStep() {
if (this.theoryStep < 3) {
this.theoryStep++;
this.runTheoryAnimation();
if (this.theorySteps && this.theorySteps[this.theoryStep]) {
this.speak(this.theorySteps[this.theoryStep]);
}
}
},
prevTheoryStep() {
if (this.theoryStep > 0) {
this.theoryStep--;
this.runTheoryAnimation();
if (this.theorySteps && this.theorySteps[this.theoryStep]) {
this.speak(this.theorySteps[this.theoryStep]);
}
}
},
// 练习题逻辑
selectOption(index, correct) {
if (this.answered) return;
this.answered = true;
this.selectedOption = index;
this.isCorrect = correct;
if (correct) {
this.score += 20;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } });
}
this.speak('答对了!太棒了!');
} else {
this.speak('再仔细想想哦。');
}
},
nextQuestion() {
if (this.currentQuestion < this.practiceQuestions.length - 1) {
this.currentQuestion++;
this.answered = false;
this.selectedOption = null;
this.isCorrect = false;
} else {
this.practiceCompleted = true;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 150, spread: 100, origin: { y: 0.6 } });
}
this.speak('恭喜你完成课内练习!');
}
},
selectOlympiadOption(index, correct) {
if (this.olympiadAnswered) return;
this.olympiadAnswered = true;
this.selectedOlympiadOption = index;
this.isOlympiadCorrect = correct;
if (correct) {
this.olympiadScore += 20;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } });
}
this.speak('挑战成功!真厉害!');
} else {
this.wrongAttempts++;
this.speak('别灰心,看看提示。');
}
},
nextOlympiad() {
if (this.currentOlympiad < this.olympiadQuestions.length - 1) {
this.currentOlympiad++;
this.olympiadAnswered = false;
this.selectedOlympiadOption = null;
this.isOlympiadCorrect = false;
this.wrongAttempts = 0;
} else {
this.olympiadCompleted = true;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 150, spread: 100, origin: { y: 0.6 } });
}
this.speak('太了不起了!奥数挑战通关!');
}
}
},
mounted() {
// 初始动画
this.runDirectAnimation();
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 AI 生成。
登录后可复制完整代码