《算法竞赛·快冲300题》每日一题:“圆内的最短距离”

news2024/10/5 9:14:10

算法竞赛·快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。
所有题目放在自建的OJ New Online Judge。
用C/C++、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。

文章目录

  • 题目描述
  • 题解
  • C++代码
  • Java代码
  • Python代码

圆内的最短距离” ,链接: http://oj.ecustacm.cn/problem.php?id=1789

题目描述

【题目描述】 小蓝最开始在一个半径为1的圆心上,圆上有m个等分点,每个点有对应的一个颜色编号。
  小蓝需要走一条给定的颜色路径,也就是每次需要到达具有该颜色的任意一个点上。
  如下图所示,图上有5个点,按照顺时针颜色编号依次为1 4 2 2 3。
  小蓝需要走的颜色路径是1 2 4 1 3 2,由于颜色2有两个点,但是最短路径如图所示。
  现在给你上述信息,求小蓝走的最短距离。
在这里插入图片描述

【输入格式】 第一行为n,表示小蓝需要完成的颜色路径的长度。
  第二行为n个数字表示给定的颜色路径。
  第三行为m,表示圆上等分点的数量。
  第四行为按照顺时针给定的m个点的颜色编号。所有数字不超过100。
【输出格式】 输出的答案与标准答案绝对误差在10^-6以内视为正确。
【输入样例】

样例16
1 2 4 1 3 2
5
1 4 2 2 3

样例25
4 2 1 3 1
6
1 2 1 3 1 4

【输出样例】

样例17.604395

样例25.732051

题解

   首先计算第x点和第y点之间的距离。原点 O O O,直线 O O Ox和 O y Oy Oy的夹角等于 α = x − y m × 2 π \alpha=\frac {x-y}{m}\times2\pi α=mxy×2π,当半径等于1时,线段xy的长度等于 2 − 2 c o s α \sqrt{2-2cos\alpha} 22cosα
在这里插入图片描述
   把本题建模为图问题。图有点和边,点是圆周上的点,边是两点间的边。把样例1画成有向图:
在这里插入图片描述

   样例1的路径要求是“1 2 4 1 3 2”,起点是颜色“1”,下一步走到颜色“2”,颜色“2”在圆周上有2个点,所以上图画了2条边。
   显然,这是一个经典的动态规划问题:多段图最短路。
   定义状态dp[][]。dp[i][j]表示走到第i步,位于j点,且j点的颜色是路径要求的颜色,dp[i][j]是从起点到第j点的最短路径长度。
   最后得到的dp[n][j],是走完了n步,位于j点,且j点的颜色是路径第n步要求的颜色。可能有多个j点的颜色满足要求,在所有的dp[n][j]中,最小的那个就是答案。
   状态转移方程:从第i-1步到第i步,按要求的颜色找下一个点,并计算这个点的最短路。
   代码第23行计算dp,有三个for循环,计算复杂度为 O ( n m 2 ) O(nm^2) O(nm2)
【重点】 多段图最短路。

C++代码

#include <bits/stdc++.h>
using namespace std;
const double INF = 10000.0;
int n,m;
int p[110],c[110];                             //p[]: 要求走的路径;c[]:圆周上点的颜色
double dp[110][110];                           //第i步走到p[i]=c[j]点的最短路径
const double pi = acos(-1.0);                  //圆周率
double dis(int x, int y){                      //x和y点之间的距离
    double a = 2.0*abs(x-y)*pi/m;              //夹角a=2*pi*(x-y)/m
    return  sqrt(2-2*cos(a));
}
int main(){
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> p[i];  //输入要求的路径编号
    cin >> m;
    for(int j = 1; j <= m; j++) cin >> c[j];  //输入圆周上的颜色编号
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            dp[i][j] = INF;                   //初始化为无穷大
    //memset(dp,0x3f,sizeof(dp));             //这样初始化是错的,因为dp是double,不是整型
    for(int j = 1; j <= m; j++)
        if(p[1]==c[j])
            dp[1][j]=1.0;                     //圆心到第一个路径点的距离是1
    for(int i = 2; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(p[i]==c[j])                    //第i步要求的路径点 = j点的颜色编号
                for(int k = 1; k <= m; k++)
                    if(p[i-1]==c[k])          //上一步也应该符合颜色要求
                        dp[i][j] = min(dp[i][j],dp[i-1][k]+dis(k,j));       //状态转移方程
    double ans = INF;
    for(int j = 1; j <= m; j++)               //dp[n][]:第n步走到了要求的p[n]=c[j]点
        ans = min(ans, dp[n][j]);             //在所有符合要求的路径中找最短的
    printf("%.6f",ans);
    return 0;
}

Java代码

import java.util.Scanner;

public class Main {
    static final double INF = 10000.0;
    static int n, m;
    static int[] p = new int[110];
    static int[] c = new int[110];
    static double[][] dp = new double[110][110];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 1; i <= n; i++)   p[i] = sc.nextInt();
        m = sc.nextInt();
        for (int j = 1; j <= m; j++)  c[j] = sc.nextInt();
        for (int i = 1; i <= n; i++) 
            for (int j = 1; j <= m; j++) 
                dp[i][j] = INF;
        for (int j = 1; j <= m; j++) 
            if (p[1] == c[j]) 
                dp[1][j] = 1.0;
        for (int i = 2; i <= n; i++) 
            for (int j = 1; j <= m; j++) 
                if (p[i] == c[j]) 
                    for (int k = 1; k <= m; k++) 
                        if (p[i - 1] == c[k]) 
                            dp[i][j] = Math.min(dp[i][j], dp[i - 1][k] + dis(k, j));
        double ans = INF;
        for (int j = 1; j <= m; j++) 
            ans = Math.min(ans, dp[n][j]);
        System.out.printf("%.6f", ans);
    }
    static double dis(int x, int y) {
        double a = 2.0 * Math.abs(x - y) * Math.acos(-1.0) / m;
        return Math.sqrt(2 - 2 * Math.cos(a));
    }
}

Python代码

import math
INF = 10000.0
n = int(input())
p =[0]+ list(map(int, input().split()))
m = int(input())
c =[0]+ list(map(int, input().split()))
dp = [[INF] * 110 for _ in range(110)]
def dis(x, y):
    a = 2.0 * abs(x - y) * math.acos(-1) / m
    return math.sqrt(2 - 2 * math.cos(a))
for j in range(1, m+1):
    if p[1] == c[j]:  dp[1][j] = 1.0
for i in range(2, n+1):
    for j in range(1, m+1):
        if p[i] == c[j]:
            for k in range(1, m+1):
                if p[i-1] == c[k]:
                    dp[i][j] = min(dp[i][j], dp[i-1][k] + dis(k, j))
ans = INF
for j in range(1, m+1):   ans = min(ans, dp[n][j])
print("%.6f" % ans)

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

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

相关文章

第五章 Opencv图像处理框架实战 5-10 文档扫描OCR识别

一、整体流程演示 上一篇我们进行了银行卡数字识别,这次我们利用opnecv等基础图像处理方法实现文档扫描OCR识别,该项目可以对任何一个文档,识别扫描出该文档上所有的文字信息。 为了方便后续程序运行,大家可以在Run->Edit Configuration中配置相关参数,选择相应编译器…

使用PostgreSQL构建强大的Web应用程序:最佳实践和建议

PostgreSQL是一个功能强大的开源关系型数据库,它拥有广泛的用户群和活跃的开发社区。越来越多的Web应用选择PostgreSQL作为数据库 backend。如何充分利用PostgreSQL的特性来构建健壮、高性能的Web应用?本文将给出一些最佳实践和建议。 一、选择合适的PostgreSQL数据类型 Pos…

CentOS系统环境搭建(三)——Centos7安装DockerDocker Compose

centos系统环境搭建专栏&#x1f517;点击跳转 Centos7安装Docker&Docker Compose 使用 yum 安装Docker 内核 [rootVM-4-17-centos ~]# uname -r 3.10.0-1160.88.1.el7.x86_64Docker 要求 CentOS 系统的内核版本高于 3.10 更新 yum yum update安装需要的软件包&#x…

Kubernetes Pod控制器

Pod控制器及其功用 Pod控制器&#xff0c;又称之为工作负载&#xff08;workload&#xff09;&#xff0c;是用于实现管理pod的中间层&#xff0c;确保pod资源符合预期的状态&#xff0c;pod的资源出现故障时&#xff0c;会尝试进行重启&#xff0c;当根据重启策略无效&#xf…

Field injection is not recommended

文章目录 1. 引言2. 不推荐使用Autowired的原因3. Spring提供了三种主要的依赖注入方式3.1. 构造函数注入&#xff08;Constructor Injection&#xff09;3.2. Setter方法注入&#xff08;Setter Injection&#xff09;3.3. 字段注入&#xff08;Field Injection&#xff09; 4…

并发编程系列-CompletableFuture

利用多线程来提升性能&#xff0c;实质上是将顺序执行的操作转化为并行执行。仔细观察后&#xff0c;你还会发现在顺序转并行的过程中&#xff0c;一定会牵扯到异步化。举个例子&#xff0c;现在下面这段示例代码是按顺序执行的&#xff0c;为了优化性能&#xff0c;我们需要将…

管家婆软件被删除了怎样恢复?

一、使用了云服务器 使用了云服务器&#xff0c;数据不会丢失&#xff0c;只需要重新安装就好了。 1、如果使用的是B/S架构的&#xff0c;比如ERP等&#xff0c;我们可以直接把网址复制到浏览器&#xff0c;访问即可。 2、如果使用的是C/S架构的&#xff0c;比如辉煌2&#x…

每天一道leetcode:剑指 Offer 34. 二叉树中和为某一值的路径(中等图论深度优先遍历递归)

今日份题目&#xff1a; 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例1 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSu…

三维直方图

三维直方图更直观&#xff0c;借助matlab的bar3&#xff0c;可以绘制三维直方图。 clc; clearvars; cimread(lena.jpg); width 0.8; %默认值是0.8&#xff0c;根据需要修改。 % hbar3(c,width,r); hbar3(c); set(h,EdgeColor,r) % set(h,facecolor,b) % set(h(1),facecolor…

提速 40%,融云基于 QUIC 深度优化通信协议

8 月 17 日&#xff08;本周四&#xff09;&#xff0c;融云直播课从排查问题到预警风险&#xff0c;社交产品如何更好保障体验、留住用户&#xff1f;欢迎点击报名~ 各分位&#xff08;P99、P95、P50&#xff09;连接速度提升 30%~50%&#xff1b;关注【融云全球互联网通信云】…

macOS CLion 使用 bits/stdc++.h

macOS 下 CLion 使用 bits/stdc.h 头文件 terminal运行 brew install gccCLion里配置 -D CMAKE_CXX_COMPILER/usr/local/bin/g-11

Microsoft ISA服务器配置及日志分析

Microsoft ISA 分析器工具&#xff0c;可分析 Microsoft ISA 服务器&#xff08;或 Forefront 威胁管理网关服务器&#xff09;的日志并生成安全和流量报告。支持来自 Microsoft ISA 服务器组件的以下日志&#xff1a; 数据包过滤器ISA 服务器防火墙服务ISA 服务器网络代理服务…

【0基础学爬虫】爬虫基础之网络请求库的使用

大数据时代&#xff0c;各行各业对数据采集的需求日益增多&#xff0c;网络爬虫的运用也更为广泛&#xff0c;越来越多的人开始学习网络爬虫这项技术&#xff0c;K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章&#xff0c;为实现从易到难全方位覆盖&#xff0c;特设【0基础学…

Qt5开发环境-银河麒麟V10ARM平台

目录 前言1.源码下载2.编译安装2.1 安装依赖2.2 编译2.3 遇到的问题2.4 安装 3.编译qtwebengine3.1 安装依赖库3.2 编译3.3 遇到的问题3.4 安装 4.配置开发环境5.测试6.程序无法输入中文的问题总结 前言 近期因参与开发的某个软件需要适配银河麒麟v10arm 平台&#xff0c;于是…

算法与数据结构(五)--二叉树入门

符号表的增删查操作&#xff0c;随着元素个数N的增多&#xff0c;其耗时也是线性增多的&#xff0c;时间复杂度都是O(n)&#xff0c;为了提高运算效率&#xff0c;我们学习树这种数据结构。 目录 一.树的基本定义 二.树的相关术语 三.二叉树的基本定义 四.二叉树的链表实现…

mysql-5.5.62-win32安装与使用

1.为啥是这个版本而不是当前最新的8.0&#xff1f; 因为我要用32位。目前mysql支持win32的版本最新只到5.7.33。 首先&#xff0c;到官网MySQL :: MySQL Downloads 然后选 选一个自己喜欢的版本就好。我这里是如标题版本。下载32位的zip。然后回来解压。 完了创建系统环境变…

【boost网络库从青铜到王者】第三篇:asio网络编程中的buffer缓存数据结构

文章目录 1、关于buffer数据结构1.1、简单概括一下&#xff0c;我们可以用buffer() 函数生成我们要用的缓存存储数据。1.2、但是这太复杂了&#xff0c;可以直接用buffer函数转化为send需要的参数类型:1.3、output_buf可以直接传递给该send接口。我们也可以将数组转化为send接受…

一百五十五、Kettle——Linux上安装的kettle9.3连接MySQL数据库

一、目的 kettle9.3在Linux上成功安装后&#xff0c;就建立数据库连接&#xff0c;第一个就是MySQL数据库 二、前提准备 提前准备好MySQL驱动包 &#xff08;一&#xff09;MySQL版本 &#xff08;二&#xff09;注意&#xff1a;由于我的MySQL版本比较高&#xff0c;所以特…

vue 路由地址把#去掉

在路由对象里边添加history模式就不显示# mode:history // 4.通过规则创建对象 const router new VueRouter({routes,// 默认模式为hash 带# // history 不带#mode:history })想把端口号8000换成其他的 比如我这样的3000更换端口号教程

【实际开发19】- 压测 / 调优准备

目录 1. Jmeter 2. Jmeter 环境部署 1. 配置 : 临时修改语言 ~ Options → Choose Language → Chinese 3. Jmeter 并发测试 0. 提示 : Postman 测试是“串行”的 , 无法测试并发请求 1. daiding 1. Jmeter 下载 : Apache JMeter - Download Apache JMeter 详参&#xf…