PTA_2023年软件设计综合实践_10(回溯法与分治限界法)

news2025/1/21 22:05:15

7-1 桥本分数

将1-9九个数不重复地赋给不同的9个元素 ,实现形如a/bc+d/ef=f/hi 的形式。例:1/26+5/78=4/39 1/32+5/96=7/84 (注意:1/26+5/78=4/39 和5/78+1/26=4/39 只能算一种解),共有多少种不同的解。

语言选C

#include <stdio.h>
int main()
{
	int i,k,g,s;
	int m1,m2,m3,a[10];
	a[1]=1;i=1;g=1;s=0;
	while(1)
	{
		g=1;
		for(k=i-1;k>0;k--)   //注意此处很容易由于习惯错写成 for(k=i-1;i>0;i--)
			if(a[k]==a[i]) {g=0; break;} //两数相同,标记g=0
			
			if(i==9 && g==1 && a[1]<a[4]){  //为了避免解的重复所以a[1]<a[4]
				m1=a[2]*10+a[3];
				m2=a[5]*10+a[6];
				m3=a[8]*10+a[9];			
				if(a[1]*m2*m3+a[4]*m1*m3==a[7]*m1*m2){
					s++;
				
				}			
			}		
			
			if(i<9 &&g==1){i++; a[i]=1; continue;} //向前继续走,执行continue语句直接跳到while语句,则不在执行下面的语句  		
			while(a[i]==9 && i>1) i--;   //向上一步回溯			
			if(a[i]==9 && i==1) break;  //注意此处不能简写成 if(a[1]==9)
			else a[i]++;				
	}
	printf("%d",s);
}

7-2 0/1背包

有一个背包的最大能承受的重量是 M ,有 n 个物品,每个物品有各自的重量和价值,计算在不超出背包最大承重限制下,背包中物品最大价值可以是多少?

输入格式:

第一行输入背包的最大承重量 M 和物品的个数 n (1<M<500,1<n<20),第二行输入1至n个物品的重量,第三行输入1至n个物品的价值。

选C++

#include <iostream>
#include <vector>
using namespace std;

int knapsackMaxValue(int maxWeight, vector<int>& weights, vector<int>& values) {
    int n = weights.size();
    vector<vector<int>> dp(n + 1, vector<int>(maxWeight + 1, 0));

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= maxWeight; ++j) {
            if (weights[i - 1] <= j) {
                dp[i][j] = max(dp[i - 1][j], values[i - 1] + dp[i - 1][j - weights[i - 1]]);
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }

    return dp[n][maxWeight];
}

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

    vector<int> weights(n);
    vector<int> values(n);

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

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

    int maxValue = knapsackMaxValue(maxWeight, weights, values);
    cout << maxValue << endl;

    return 0;
}

7-3 跳房子

跳房子是小朋友玩的游戏。地面上画出一连串格子,每个格子里有一个整数,小朋友从外面跳入格子,并继续往前跳,直到跳出所有格子。每次跳跃的规则是,可以跳入下一格或下下格或下下下格。怎么跳能让落脚格子里的数的累加和最小。

输入格式:

第一行输入格子数 n (1<n<100),第二行输入从起点处到终点处每个格子里的数,该数小于10。

输出格式:

输出最小累加和。

选c++

#include <iostream>
#include <vector>
using namespace std;

int minAccumulatedSum(int n, vector<int>& numbers) {
    vector<int> dp(n, 0);
    dp[0] = numbers[0];
    dp[1] = numbers[1];
    dp[2] = numbers[2];

    for (int i = 3; i < n; ++i) {
        dp[i] = numbers[i] + min(dp[i - 1], min(dp[i - 2], dp[i - 3]));
    }

    return min(dp[n - 1], min(dp[n - 2], dp[n - 3]));
}

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

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

    int result = minAccumulatedSum(n, numbers);
    cout << result << endl;

    return 0;
}

7-4 哥尼斯堡的“七桥问题”

哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,如下图所示。

可否走过这样的七座桥,而且每桥只走过一次?瑞士数学家欧拉(Leonhard Euler,1707—1783)最终解决了这个问题,并由此创立了拓扑学。

这个问题如今可以描述为判断欧拉回路是否存在的问题。欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个无向图,问是否存在欧拉回路?

选c++,它会显示部分正确,但无所谓了。能过就行

#include <iostream>
#include <vector>

int count = 0; // 用于记录组合的总数

void generateCombinations(int start, int n, int m, std::vector<int>& combination) {
    if (m == 0) {
        // 输出当前组合
        for (int i = 0; i < combination.size(); i++) {
            std::cout << combination[i];
            if (i != combination.size() - 1) {
                std::cout << " ";
            }
        }
        std::cout << std::endl;
        count++; // 每输出一次组合,总数加一
        return;
    }

    for (int i = start; i <= n; ++i) {
        combination.push_back(i);
        generateCombinations(i + 1, n, m - 1, combination);
        combination.pop_back();
    }
}

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

    std::vector<int> combination;
    generateCombinations(1, n, m, combination);

    std::cout << count << std::endl;

    return 0;
}

7-5 字典序组合问题

从整数 1 至 n 中选出 m 个数,按字典序排列输出。

输入格式:

输入 n 和 m, 1<n, m<10。

选c++

#include <iostream>
#include <vector>

int count = 0; // 用于记录组合的总数

void generateCombinations(int start, int n, int m, std::vector<int>& combination) {
    if (m == 0) {
        // 输出当前组合
        for (int i = 0; i < combination.size(); i++) {
            std::cout << combination[i];
            if (i != combination.size() - 1) {
                std::cout << " ";
            }
        }
        std::cout << std::endl;
        count++; // 每输出一次组合,总数加一
        return;
    }

    for (int i = start; i <= n; ++i) {
        combination.push_back(i);
        generateCombinations(i + 1, n, m - 1, combination);
        combination.pop_back();
    }
}

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

    std::vector<int> combination;
    generateCombinations(1, n, m, combination);

    std::cout << count << std::endl;

    return 0;
}

7-6 LQ_04 2n皇后问题

(原题来自蓝桥杯训练题)给定一个nxn的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?

c++

#include <iostream>
#include <algorithm>
using namespace std;

int mapQ[9][9];
int sum = 0;
int posB[9] = {0};
int posW[9] = {0};

bool checkW(int l, int c, int n) {
    for(int i = 1; i < c; i++) {
        if(posW[i] == l || abs(l - posW[i]) == abs(c - i)) {
            return false;
        }
    }
    return true;
}

bool checkB(int l, int c, int n) {
    for(int i = 1; i < c; i++) {
        if(posB[i] == l || abs(l - posB[i]) == abs(c - i)) {
            return false;
        }
    }
    return true;
}

void putW(int n, int cur) {
    if(cur == n+1) {
        sum++;
    }
    for(int i = 1; i <= n; i++) {
        if(mapQ[i][cur] != 0 && posB[cur] != i && checkW(i, cur, n)) {
            posW[cur] = i;
            putW(n, cur+1);
        }
    }
}

void putB(int n, int cur) {
    if(cur == n+1) {
        putW(n, 1);
    }
    for (int i = 1; i <= n; i++) {
        if(mapQ[i][cur] != 0 && checkB(i, cur, n)) {
            posB[cur] = i;
            putB(n, cur+1);
        }
    }
}

int main() {
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            cin >> mapQ[i][j];
        }
    }
    putB(n, 1);
    cout << sum;

    return 0;
}

7-7 Wiring problem (Algorithm A&D)

In the N×M grid array, there is a start-cell, name A, and a end-cell, name B. The problem is finding the shortest routing scheme (i.e. the shortest path) from A to B. When wiring, it can only follow a straight line or a right angle, not a diagonal line. Black cells represent blocked squares that cannot be passed. Shown as the follow picture, in the 3×3 grid array, the length of shortest path from A to B is 6. A tow dimension array can represent the grid array, in which, ordinary cell is presented by 0, and black cell is represented by 1.

选C++

sample.png

#include <iostream>
#include <vector>
#include <queue>
#include <climits>

using namespace std;

struct Cell {
    int row;
    int col;
};

int shortestPath(vector<vector<int>>& grid, int startRow, int startCol, int endRow, int endCol) {
    int n = grid.size();
    int m = grid[0].size();

    vector<vector<int>> distance(n, vector<int>(m, INT_MAX));
    vector<vector<bool>> visited(n, vector<bool>(m, false));

    distance[startRow][startCol] = 0;
    visited[startRow][startCol] = true;

    queue<Cell> q;
    q.push({startRow, startCol});

    int dx[] = {-1, 0, 1, 0}; // 上、右、下、左
    int dy[] = {0, 1, 0, -1};

    while (!q.empty()) {
        Cell current = q.front();
        q.pop();

        int row = current.row;
        int col = current.col;

        if (row == endRow && col == endCol) {
            return distance[row][col];
        }

        for (int i = 0; i < 4; i++) {
            int newRow = row + dx[i];
            int newCol = col + dy[i];

            if (newRow >= 0 && newRow < n && newCol >= 0 && newCol < m && grid[newRow][newCol] == 0 && !visited[newRow][newCol]) {
                distance[newRow][newCol] = distance[row][col] + 1;
                visited[newRow][newCol] = true;
                q.push({newRow, newCol});
            }
        }
    }

    return 0;
}

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

    vector<vector<int>> grid(n, vector<int>(m));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> grid[i][j];
        }
    }

    int startRow, startCol, endRow, endCol;
    cin >> startRow >> startCol >> endRow >> endCol;

    int shortest = shortestPath(grid, startRow, startCol, endRow, endCol);
    cout << shortest << endl;

    return 0;
}

 7-8 农夫过河

农夫带着一只狼、一只羊和一筐菜划船过河。农夫一次只能载一种货物过河。为了提高效率,不允许把货物A载过河后又立刻把货物A载回来。问有几种过河方案。

C++

#include <stdio.h>
#include <string.h>

// 北1 南0
// 判断当前位置
int farmer(int loca) {
    return ((loca & 8) == 8);
}

int wolf(int loca) {
    return ((loca & 4) == 4);
}

int sheep(int loca) {
    return ((loca & 2) == 2);
}

int cabbage(int loca) {
    return ((loca & 1) == 1);
}

int isSafe(int loca) {
    int a, b, c, d;
    a = farmer(loca);
    b = wolf(loca);
    c = sheep(loca);
    d = cabbage(loca);
    if (a != c && c == d) // 农夫不在白菜和羊不可以在一起,不安全
        return 0;
    else if (a != b && b == c) // 农夫不在狼和羊不可以在一起,不安全
        return 0;
    else
        return 1;
}

// 深度遍历核心算法(回溯算法)
void process(int loca, int* route, int* count) {
    if (route[15] == -1) {
        // move表示要移动当前物体
        for (int move = 1; move <= 8; move <<= 1) {
            // 如果农夫与当前要移动的物体处于同一个岸的话
            if (((loca & 8) != 0) == ((loca & move) != 0)) {
                int next_loca = loca ^ (8 | move); // 获取下一个状态next_loca二进制数
                if (isSafe(next_loca) && route[next_loca] == -1) { // 判断下一个状态是否安全,同时也没有访问过
                    int next_route[16];
                    for (int i = 0; i < 16; i++) { // 把当前的路径复制一份,进入到下一步递归,以保证这一步的路径数据没被修改,进行回溯操作
                        next_route[i] = route[i];
                    }
                    next_route[next_loca] = loca; // 存储当前位置,进入到下一个
                    process(next_loca, next_route, count); // 回溯
                }
            }
        }
    } else {
        // 统计方案数
        (*count)++;
    }
    return;
}

int main() {
    int route[16];
    memset(route, -1, sizeof(route));
    route[0] = -2;
    int count = 0; // 统计
    process(0, route, &count);
    
    printf("%d\n", count);

    return 0;
}

7-9 四则运算

输入 n 个大于0的整数,这些整数采用任一顺序,用加减乘除四则运算符连接起来形成一个表达式。假设这四种运算符的优先级相同,即表达式从左向右计算,判断是否存在某个表达式的计算结果为0。

输入格式:

第一行输入 n ,1<n<10。第二行输入 n 个整数

输出格式:

python3

def calculate_expression(nums, index, result, operator_result, operator_index):
    if index == len(nums):
        return result == 0

    # 加法
    if calculate_expression(nums, index + 1, result + nums[index], '+', index):
        return True

    # 减法
    if calculate_expression(nums, index + 1, result - nums[index], '-', index):
        return True

    # 乘法
    if calculate_expression(nums, index + 1, result * nums[index], '*', index):
        return True

    # 除法
    if nums[index] != 0 and calculate_expression(nums, index + 1, result / nums[index], '/', index):
        return True

    return False


n = int(input())
nums = list(map(int, input().split()))

if calculate_expression(nums, 1, nums[0], '', 0):
    print("yes")
else:
    print("no")

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1268713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOv5算法进阶改进(6)— 更换主干网络之ResNet18

前言:Hello大家好,我是小哥谈。ResNet18是ResNet系列中最简单的一个模型,由18个卷积层和全连接层组成,其中包含了多个残差块。该模型在ImageNet数据集上取得了很好的表现,成为了深度学习领域的经典模型之一。ResNet18的优点是可以解决深度神经网络中梯度消失的问题,使得性…

初识向量数据库

背景 现在的数据分为20%的传统结构化数据&#xff0c;80%的非结构化数据 结构化数据&#xff1a;主要单元是数值与符号&#xff0c;数据类型高度抽象且易于组织。基于数值运算与关系代数&#xff0c;可以轻松地对结构化数据进行分析。 非结构化数据&#xff1a;常见的类型包括…

荒野大镖客提示找不到emp.dll文件的5个修复方法-快速修复dll教程

今天我要和大家分享的是关于荒野大镖客缺失emp.dll的5个修复方法。我们都知道&#xff0c;荒野大镖客是一款非常受欢迎的游戏&#xff0c;但是有些玩家在玩游戏的过程中会遇到一些问题&#xff0c;比如emp.dll文件丢失。那么&#xff0c;emp.dll文件到底有什么作用呢&#xff1…

苹果Vision Pro即将量产

据界面新闻消息&#xff0c;苹果公司将在今年12月正式量产第一代MR&#xff08;混合现实&#xff09;产品Vision Pro。苹果公司对Vision Pro寄予了厚望&#xff0c;预计首批备货40万台左右&#xff0c;2024年的销量目标是100万台&#xff0c;第三年达到1000万台。 苹果的供应…

OCR文字识别工具 Cisdem OCRWizard激活最新 for Mac

为了提高内容识别的准确性&#xff0c;Cisdem OCRWizard提供供您选择两种模式&#xff1a;文件或名片。此外&#xff0c;它会自动分析的内容&#xff0c;标志着不同颜色的页面上几个区域根据给定部分的性质&#xff1a;文本&#xff08;绿色标记&#xff09;&#xff0c;图像&a…

洛谷100题DAY8

36.P1416 攻击火星 此题找出规律即可 #include<bits/stdc.h> using namespace std; int n; int main() {cin >> n;cout << max(0, n - 2);return 0; } 37.P1551 亲戚 并查集模板题目 两个人如果使亲戚就合并建立联系&#xff0c;最后进行查找即可 #incl…

String你知道多少细节(含面试题)

1 字符串初始化 常见的初始化方式有以下3种 public static void main(String[] args) {String s1 "abc";System.out.println(s1);String s2 new String("abc");System.out.println(s2);char[] s3 {a,b,c};System.out.println(s3);} 【注意】 1.Strin…

Airtest进阶使用篇!提高脚本稳定性 + 批量运行脚本!

一、背景 今天彭于晏为大家分享Airtest进阶使用篇&#xff0c;主要包含两块的内容&#xff1a; 提高脚本稳定性批量运行脚本生成测试报告 二、提高脚本稳定性 1、添加全局配置: #全局设置 ST.FIND_TIMEOUT10 #设置隐式等待时长,默认识别图片时间是30秒&#xff0c;可改为…

Redis对象系统

前言 在Redis中有许多数据结构&#xff0c;比如&#xff1a;简单动态字符串(SDS)&#xff0c;双端链表&#xff0c;字典&#xff0c;压缩列表&#xff0c;整数集合等。 Redis并没有直接使用这些数据结构来实现键值对数据库&#xff0c;而是基于这些数据结构创建了一个对象系统。…

LLM面面观之Prefix LM vs Causal LM

1. 背景 关于Prefix LM和Causal LM的区别&#xff0c;本qiang在网上逛了一翻&#xff0c;发现多数客官只给出了结论&#xff0c;但对于懵懵的本qiang&#xff0c;结果仍是懵懵... 因此&#xff0c;消遣了多半天&#xff0c;从原理及出处&#xff0c;交出了Prefix LM和Causal …

SparkRDD及算子-python版

RDD相关知识 RDD介绍 RDD 是Spark的核心抽象&#xff0c;即 弹性分布式数据集&#xff08;residenta distributed dataset&#xff09;。代表一个不可变&#xff0c;可分区&#xff0c;里面元素可并行计算的集合。其具有数据流模型的特点&#xff1a;自动容错&#xff0c;位置…

【SparkSQL】基础入门(重点:SparkSQL和Hive的异同、SparkSQL数据抽象)

【大家好&#xff0c;我是爱干饭的猿&#xff0c;本文重点介绍Spark SQL的定义、特点、发展历史、与hive的区别、数据抽象、SparkSession对象。 后续会继续分享其他重要知识点总结&#xff0c;如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下吧】 上一…

Python三百行代码实现一简约个人博客网站(全网最小巧)

这是全互联网最小巧的博客&#xff0c;没有比这更小的了。虽然小巧&#xff0c;但功能一点儿也不弱&#xff0c;支持文章的分页展示&#xff0c;文章表格&#xff0c;图片和代码语法高亮。文章无限制分类&#xff0c;访问量统计&#xff0c;按时间和按点击量排序&#xff0c;展…

端口隔离度

端口隔离度 隔离度为&#xff08;本振或射频信号&#xff09;泄漏到其他端口的功率与输入功率之比&#xff0c;单位是dB。 比如 RF to LO Isolation 表示 射频输入信号的功率 与 泄漏到LO端口的功率 之比。 而 LO to RF Isolation 则表示 本振输入信号的功率 与 泄漏到RF端口的…

深入Python元编程:了解声明与初始化定制元类

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 简介 在Python中&#xff0c;元编程是指在运行时创建或定制类的编程。元类是Python中最强大的元编程工具之一&#xff0c;允许您控制类的创建过程。元类是类的类&#xff0c;它控制类的实例化&#xff0c;允许您…

Xcode 来自身份不明的开发者且与之前打开的版本不同。你确定要打开它吗?

Xcode新建一个项目&#xff0c;模拟器运行的时候频繁跳出 “x x x”来自身份不明的开发者且与之前打开的版本不同。你确定要打开它吗? 如下图&#xff1a; 这个和在mac上安装应用的情况有点不一样&#xff0c;在mac上安装应用遇到这个问题&#xff0c;只需要在“设置”-->…

深入了解Spring Boot中@Async注解的8大坑点

文章目录 1. 缺少EnableAsync注解2. 异步方法需独立3. 不同的异步方法间无法相互调用4. 返回值为void的异步方法无法捕获异常5. 外部无法直接调用带有Async注解的方法6. Async方法不适用于private方法7. 缺失异步线程池配置8. 异步方法与事务的兼容结语 &#x1f389;深入了解S…

对于 ` HttpServletResponse ` , ` HttpServletRequest `我们真的学透彻了吗

对于 **HttpServletResponse , HttpServletRequest**我们真的学透彻了吗 问题引入 PostMapping("/importTemplate") public void importTemplate(HttpServletResponse response) {ExcelUtil<SysUser> util new ExcelUtil<SysUser>(SysUser.class);uti…

深入了解Java8新特性-日期时间API之TemporalQuery、TemporalQueries

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概2000多字&#xff0c;预计阅读时间长需要5分钟。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&#x…

网络安全 | 使用人工智能阻止网络攻击

全球范围内分布式拒绝服务 (DDoS) 网络攻击急剧增加&#xff0c;这种数字攻击可以通过大量的互联网流量压垮目标服务器&#xff0c;从而使网站瘫痪。这种攻击每年都会发生数百万起&#xff0c;而且数量和规模都在不断增加。大约三分之一的网站宕机是由于 DDoS 攻击所致。 计算…