DESE巅峰赛#1题解-DESE(团队)论坛-团队讨论区-LZM's Blog

DESE巅峰赛#1题解

接下来是所有的题解…

好的,这是完整的6道题目及详细题解,包含C++代码实现。

## **题目1:小明的糖果分配**

### **题目分析**
这是一个简单的模运算问题。只需要计算 `n % m`:
– 如果余数为0,说明可以平分,输出 `n / m`
– 如果余数不为0,小明需要吃掉余数颗糖果,输出余数

### **C++代码**
“`cpp
#include <iostream>
using namespace std;

int main() {
int n, m;
cin >> n >> m;

if (n % m == 0) {
cout << n / m << endl;
} else {
cout << n % m << endl;
}

return 0;
}
“`

### **代码说明**
– 时间复杂度:O(1)
– 空间复杂度:O(1)
– 关键点:使用取模运算判断是否能够整除

## **题目2:小明的数字反转**

### **题目分析**
将数字反转可以通过数学运算实现:
1. 不断取原数字的个位数(`n % 10`)
2. 将个位数加到结果中(`result = result * 10 + digit`)
3. 原数字除以10(`n /= 10`)
4. 重复直到原数字为0

### **C++代码**
“`cpp
#include <iostream>
using namespace std;

int main() {
int n;
cin >> n;

// 处理特殊情况:n为0
if (n == 0) {
cout << 0 << endl;
return 0;
}

int result = 0;
while (n > 0) {
result = result * 10 + n % 10;
n /= 10;
}

cout << result << endl;
return 0;
}
“`

### **代码说明**
– 时间复杂度:O(d),d为数字的位数
– 空间复杂度:O(1)
– 注意:这种方法自动处理了前导零的问题

## **题目3:小明的购物计划**

### **题目分析**
这是一个经典的贪心问题。要买到最多的玩具,应该优先购买价格便宜的玩具:
1. 将玩具价格排序
2. 从最便宜的开始买,直到钱不够为止

### **C++代码**
“`cpp
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main() {
int n, k;
cin >> n >> k;

vector<int> prices(n);
for (int i = 0; i < n; i++) {
cin >> prices[i];
}

// 按价格从小到大排序
sort(prices.begin(), prices.end());

int count = 0;
int total_cost = 0;

for (int i = 0; i < n; i++) {
if (total_cost + prices[i] <= k) {
total_cost += prices[i];
count++;
} else {
break;
}
}

cout << count << endl;
return 0;
}
“`

### **代码说明**
– 时间复杂度:O(n log n),主要是排序的复杂度
– 空间复杂度:O(n)
– 贪心策略证明:优先买便宜的玩具可以得到最大数量

## **题目4:小明的迷宫探险**

### **题目分析**
使用深度优先搜索(DFS)或广度优先搜索(BFS)来遍历迷宫:
1. 从起点开始搜索
2. 标记访问过的位置,避免重复计数
3. 向四个方向扩展(上、下、左、右)
4. 统计所有能到达的格子数量

### **C++代码**
“`cpp
#include <iostream>
#include <vector>
#include <string>
using namespace std;

// 四个方向:上、右、下、左
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

int n, m;
vector<string> maze;
vector<vector<bool>> visited;

// DFS搜索
int dfs(int x, int y) {
// 越界检查
if (x < 0 || x >= n || y < 0 || y >= m) return 0;
// 墙壁或已访问检查
if (maze[x][y] == ‘#’ || visited[x][y]) return 0;

visited[x][y] = true;
int count = 1; // 当前格子

// 向四个方向搜索
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
count += dfs(nx, ny);
}

return count;
}

int main() {
cin >> n >> m;
maze.resize(n);
visited.resize(n, vector<bool>(m, false));

for (int i = 0; i < n; i++) {
cin >> maze[i];
}

int start_x, start_y;
cin >> start_x >> start_y;
// 题目中行列从1开始,程序中从0开始
start_x–;
start_y–;

int result = dfs(start_x, start_y);
cout << result << endl;

return 0;
}
“`

### **代码说明**
– 时间复杂度:O(n × m),每个格子最多访问一次
– 空间复杂度:O(n × m),用于存储访问标记
– 注意:起点坐标需要从1-based转换为0-based

## **题目5:小明的数列问题**

### **题目分析**
这是一个动态规划问题:
– 状态定义:dp[i] 表示数列第i项的值
– 递推关系:dp[i] = dp[i-1] + dp[i-3]
– 初始条件:dp[1] = dp[2] = dp[3] = 1
– 由于结果很大,需要取模

### **C++代码**
“`cpp
#include <iostream>
#include <vector>
using namespace std;

const int MOD = 10007;

int main() {
int n;
cin >> n;

if (n <= 3) {
cout << 1 << endl;
return 0;
}

vector<int> dp(n + 1);
dp[1] = dp[2] = dp[3] = 1;

for (int i = 4; i <= n; i++) {
dp[i] = (dp[i-1] + dp[i-3]) % MOD;
}

cout << dp[n] << endl;
return 0;
}
“`

### **优化版本(节省空间)**
“`cpp
#include <iostream>
using namespace std;

const int MOD = 10007;

int main() {
int n;
cin >> n;

if (n <= 3) {
cout << 1 << endl;
return 0;
}

int a = 1, b = 1, c = 1, d;
for (int i = 4; i <= n; i++) {
d = (c + a) % MOD;
a = b;
b = c;
c = d;
}

cout << c << endl;
return 0;
}
“`

### **代码说明**
– 时间复杂度:O(n)
– 空间复杂度:O(1)(优化版本)
– 关键点:理解递推关系,注意取模运算

## **题目6:小明的素数对**

### **题目分析**
需要解决两个问题:
1. 判断一个数是否为素数
2. 枚举所有可能的数对(i, j),检查i, j和i+j是否都是素数

优化:预先计算1到2n范围内的所有素数(因为i+j最大为2n)

### **C++代码**
“`cpp
#include <iostream>
#include <vector>
using namespace std;

// 埃拉托斯特尼筛法求素数
vector<bool> getPrimes(int n) {
vector<bool> isPrime(n + 1, true);
isPrime[0] = isPrime[1] = false;

for (int i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= n; j += i) {
isPrime[j] = false;
}
}
}
return isPrime;
}

int main() {
int n;
cin >> n;

// 预计算素数,最大需要判断2n
vector<bool> isPrime = getPrimes(2 * n);

int count = 0;
// 枚举所有素数对
for (int i = 2; i <= n; i++) {
if (!isPrime[i]) continue; // i必须是素数
for (int j = i + 1; j <= n; j++) {
if (!isPrime[j]) continue; // j必须是素数
if (isPrime[i + j]) { // i+j也必须是素数
count++;
}
}
}

cout << count << endl;
return 0;
}
“`

### **代码说明**
– 时间复杂度:O(n²),但实际运行很快,因为素数比较稀疏
– 空间复杂度:O(n)
– 优化:使用筛法预处理素数,使得判断素数的时间复杂度为O(1)

## **总结**

这6道题目涵盖了竞赛编程的基础知识点:

1. **基础语法**:输入输出、条件判断、循环
2. **数学运算**:取模、数字反转
3. **贪心算法**:排序后选择最优解
4. **搜索算法**:DFS遍历图或网格
5. **动态规划**:状态转移和递推关系
6. **数论基础**:素数判断和筛法

建议按照题目顺序练习,逐步提升编程能力和算法思维。每道题目都提供了清晰的解题思路和代码实现,适合团队学习和讨论。

请登录后发表评论

    没有回复内容

LZM‘s AI

LZM‘s AI

LZM's Blog

LZM's Blog