【OJ for Divide and Conquer】OJ题解

news2024/11/23 18:31:40

文章目录

  • A - Ultra-QuickSort
  • B - Hanoi Tower Troubles Again! [找规律+递归]
  • C - Fibonacci Again[找规律]
  • E - [Fire Net](https://programmerall.com/article/7276104269/)[DFS 搜索 ⭐⭐]
  • F - Gridland[找规律]
  • G - Maximum Subarray Sum[动态规划/分治..经典⭐]
  • I - Quoit Design[最近点对距离]

A - Ultra-QuickSort

In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,

Ultra-QuickSort produces the output
0 1 4 5 9 .

Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
简单来说,就是有一组无序的数组,求两两交换的最小次数使得数组升序排列。
分析:要使得数组升序排列,
here 🙋‍ 查看归并算法总结
我们只需要在归并排序的算法中,在合并时,判断前面子数列的值是否大于后面子序列的值。
在这里插入图片描述
注意一个易错点,每轮loop都必须要指定退出条件,在这里条件就是当两个子序列的指针指向同一个数时,退出。

if(l>=r) return;

整体代码如下,

#include<iostream>
#include<vector>
using namespace std;
int arr[500010];
int tmp[500010];
int sum=0;
//归并算法
void mergesort(int l,int r){
    if(l>=r) return;
    int mid=(l+r)/2;
    mergesort(l,mid);
    mergesort(mid+1,r);

    int i=l,j=mid+1,k=l;
    while(i<=mid && j<=r){
        // cout<<"f";       while(arr[i]<=arr[j] && i<=mid) tmp[k++]=arr[i++];
        while(arr[i]>arr[j] && j<=r) 
        {
            tmp[k++]=arr[j++];
            sum+=mid+1-i;
        }
    }
    while(i<=mid) tmp[k++]=arr[i++];
    while(j<=r) tmp[k++]=arr[j++];
    for(int k=l;k<=r;k++)
        arr[k]=tmp[k];
}
int main(){
    int n;
    while(cin>>n && n){
        for(int i=0;i<n;i++){
            cin>>arr[i];
        }
        sum=0;
        mergesort(0,n-1);
        cout << sum << endl;
    }
}

B - Hanoi Tower Troubles Again! [找规律+递归]

People stopped moving discs from peg to peg after they know the number of steps needed to complete the entire task. But on the other hand, they didn’t not stopped thinking about similar puzzles with the Hanoi Tower. Mr.S invented a little game on it. The game consists of N pegs and a LOT of balls. The balls are numbered 1,2,3… The balls look ordinary, but they are actually magic. If the sum of the numbers on two balls is NOT a square number, they will push each other with a great force when they’re too closed, so they can NEVER be put together touching each other.
The player should place one ball on the top of a peg at a time. He should first try ball 1, then ball 2, then ball 3… If he fails to do so, the game ends. Help the player to place as many balls as possible. You may take a look at the picture above, since it shows us a best result for 4 pegs.

简单来说,看每次提供的柱子数可以承载多少个圆盘,使得每根柱子上相邻两圆盘的加和必定为平方数。
分析:这道题看起来很难,实际上从简单情况入手。先看一根柱子、再看两根柱子…发现能承载圆盘的数量依次为1、3、7、11、17、23,每两个之间相差2、4、4、6、6…于是我们发现了规律。实际上,用数学方法证明也能得出该结论。
在这里插入图片描述

递推公式: H a n o i ( i ) = H a n o i ( i − 1 ) + i + i % 2 Hanoi(i)=Hanoi(i-1)+i+i \% 2 Hanoi(i)=Hanoi(i1)+i+i%2
考虑到题目中有多次求解,所以我们用表格的方式将结果先提前算好存储起来。

void Hanoi(){
    table[1]=1;
    table[2]=3;
    for(int i=3;i<N;i++)
        table[i]=table[i-1]+i+i%2;
}

全部代码也就很明晰了:

#include<iostream>
using namespace std;
#define N 55
int table[N];
//打表过程 避免重复计算
void Hanoi(){
    table[1]=1;
    table[2]=3;
    for(int i=3;i<N;i++)
        table[i]=table[i-1]+i+i%2;
}
int main(){
    int n,x;
    cin>>n;
    Hanoi();
    for(int i=0;i<n;i++){
        cin>>x;
        cout<<table[x]<<endl;
        
    }
}

补充:

  • 宏定义格式
    #define 宏名 替换文本
#define N 10;               // 宏定义
int c[N];                   // 会被替换为: int c[10;]; 

C - Fibonacci Again[找规律]

There are another kind of Fibonacci numbers: F(0) = 7, F(1) = 11, F(n) = F(n-1) + F(n-2) (n>=2)

Input

Input consists of a sequence of lines, each containing an integer n. (n < 1,000,000)

Output

Print the word “yes” if 3 divide evenly into F(n).

Print the word “no” if not.

分析:注意 斐波那契数列会议非常快的速度增长,因此直接计算出结果并和3运算取余的做法不可取。我们考虑列出前面部分结果,试图找规律。嘿,还真成功了!

012345678910
71118294776123199322521843

观察表格:发现每4个为一组。在数组的第3个数时,可以被整除,也就是输出yes.

int main(){
    int n;
    int f[4]={0,0,1,0};
    while(cin>>n){
        if(f[n%4]) cout<<"yes"<<endl;
        else cout<<"no"<<endl;
    }
}

E - Fire Net[DFS 搜索 ⭐⭐]

Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.
A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.
Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.
The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.
The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.
Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration.
分析:
map中各个符号的意义:

X.%
有墙(可以避开💣)啥也没有有碉堡(可以四处散布💣)

采用DFS的思想

深度优先搜索的步骤分为
1.递归下去 2.回溯上来。
顾名思义,深度优先,则是以深度为准则,先一条路走到底,直到达到目标。这里称之为递归下去。否则既没有达到目标又无路可走了,那么则退回到上一步的状态,走其他路。这便是回溯上来。

总结DFS模板:【注意恢复现场这一步】
在这里插入图片描述

这道题的IDEA:

从左上角的元素开始进行深度搜索,一直搜索到右下角位置。使用check检查函数判断当前搜索到的位置能不能放置碉堡,若是可以放置,则将本轮的总和加一,并将此处标记为%,意思是有一座碉堡。然后继续进行深度搜索。如果已经到了最右下角位置,则回溯并记录最大值。

#include<iostream>
#include<algorithm>
using namespace std;
int n,ans=0;
char arr[5][5];

int check(int x,int y){
    for(int i=x-1;i>=0;i--){
        if(arr[i][y]=='%') return false;
        if(arr[i][y]=='X') break;
    }
    for(int i=x+1;i<n;i++){
        if(arr[i][y]=='%') return false;
        if(arr[i][y]=='X') break;
    }
    for(int i=y-1;i>=0;i--){
        if(arr[x][i]=='%') return false;
        if(arr[x][i]=='X') break;
    }
    for(int i=x+1;i<n;i++){
        if(arr[x][i]=='%') return false;
        if(arr[x][i]=='X') break;
    }
    return true;
}

//s表示当前的状态吧
void dfs(int s,int sum){
    if(s==n*n){
        ans=max(ans,sum);
        return;
    }
    int x=s/n;
    int y=s%n;
    if(arr[x][y]=='.' && check(x,y)){
        arr[x][y]='%'; //表示成功加入一个碉堡
        dfs(s+1,sum+1); //继续深度搜索
        arr[x][y]='.'; //!还原标记!
    }
    dfs(s+1,sum);
}

int main(){
    while(cin>>n && n){
        ans=0;
        for(int i=0;i<n;i++)
               cin>>arr[i]; 
        dfs(0,0);
        
        cout<<ans<<endl;
    }
}

F - Gridland[找规律]

For years, computer scientists have been trying to find efficient solutions to different computing problems. For some of them efficient algorithms are already available, these are the “easy” problems like sorting, evaluating a polynomial or finding the shortest path in a graph. For the “hard” ones only exponential-time algorithms are known. The traveling-salesman problem belongs to this latter group. Given a set of N towns and roads between these towns, the problem is to compute the shortest path allowing a salesman to visit each of the towns once and only once and return to the starting point.

The president of Gridland has hired you to design a program that calculates the length of the shortest traveling-salesman tour for the towns in the country. In Gridland, there is one town at each of the points of a rectangular grid. Roads run from every town in the directions North, Northwest, West, Southwest, South, Southeast, East, and Northeast, provided that there is a neighbouring town in that direction. The distance between neighbouring towns in directions North–South or East–West is 1 unit. The length of the roads is measured by the Euclidean distance. For example, Figure 7 shows 2 × 3-Gridland, i.e., a rectangular grid of dimensions 2 by 3. In 2 × 3-Gridland, the shortest tour has length 6.
在这里插入图片描述
分析:初一看很难,但只要从简单情况出发,找寻规律,就可得到意外之喜😊
只要多做几组你就会发现规律:只要n,m有一个为偶数,答案为n*m;都为基数,答案为n*m-1+sqrt(2)
下图是当时很潦草的草稿…浅浅看一下吧❤
在这里插入图片描述

#include<iostream>
#include<math.h>

using namespace std;

int main(){
    int N;
    double ans;
    cin>>N;
    for(int i=1;i<=N;i++){
        int n,m;
        cin>>m>>n;
        if((m*n)%2) ans=m*n*1.0-1+sqrt(2);
        else ans=m*n*1.0;
        cout<<"Scenario #"<<i<<":\n";
        printf("%.2f\n\n",ans);
    }
}

补充一个知识点:

  • prinf输出浮点数

>% - 0 m.n 格式字符
下面对组成格式说明的各项加以说明:
①%:表示格式说明的起始符号,不可缺少。
②-:有-表示左对齐输出,如省略表示右对齐输出。
③0:有0表示指定空位填0,如省略表示指定空位不填。
④m.n:m指域宽,即对应的输出项在输出设备上所占的字符数。N指精度。用于说明输出的实型数的小数位数。为指定n时,隐含的精度为n=6位。

G - Maximum Subarray Sum[动态规划/分治…经典⭐]

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
寻找和最大的子序列,并返回最大值
分析:
刚拿到这道题就想到了用动态规划的方法做。在每一步,我们维护两个变量,一个是全局最优,就是到当前元素为止最优的解是,一个是局部最优,就是必须包含当前元素的最优的解。其中这个局部最优,要么是从这个元素开始的新序列,要么是包含上一个元素的序列。
dp[i]=max(dp[i-1]+arr[i],arr[i]) dp是维护的局部最优解,arr是输入的数组。

#include<iostream>
#include<algorithm>
#include<climits> 
using namespace std;
#define N 200100
int main(){
    int dp[N];
    int arr[N];
    int ans=INT_MIN;
    //INT_MIN:-2147483648 || INT_MAX:2147483647
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>arr[i];
    dp[0]=arr[0];
    for(int i=1;i<n;i++)
    {
        dp[i]=max(dp[i-1]+arr[i],arr[i]);
        ans=max(ans,dp[i]);
    }
    cout<<ans<<endl;
    
}

注意这道题目易错点是数组大小的开辟,小心审题就是了。

  1. 做题时候遇到了:runtime error (运行时错误)就是程序运行到一半,程序就崩溃了。可能有以下几种情况:

    ①除以零
    ②数组越界:int a[3]; a[10000000]=10;
    ③指针越界:int * p; p=(int *)malloc(5 * sizeof(int)); *(p+1000000)=10;
    ④使用已经释放的空间:int * p; p=(int *)malloc(5 * sizeof(int));free§; *p=10;
    ⑤数组开得太大,超出了栈的范围,造成栈溢出:int a[100000000];

I - Quoit Design[最近点对距离]

Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.
In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring.

Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0.
Input
The input consists of several test cases. For each case, the first line contains an integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0.
Output
For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places.

分析:这道题的难点在于读懂题!想要最大的圈直径,使得圈只能套到一个物品。其实就是找最近的两个点,之间的距离就是目标圈的直径。那么就变成了最近点对问题。链接 这个链接展示了详细的求解过程,可以仔细研究。
仔细看

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

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

相关文章

在线运行C++的网站(欢迎补充)

1、https://cpp.sh/ 谷歌打开&#xff0c;好用 2、https://godbolt.org/ 会显示汇编

Beyond Compare4 30天试用到期的解决办法

相信很多小伙伴都有在使用Beyond Compare 4软件&#xff0c;如果我们没有激活该软件&#xff0c;就只有30天的评估使用期&#xff0c;那么过了这30天后我们怎么继续使用呢&#xff1f;下面小编就来为大家介绍方法。 打开Beyond Compare4&#xff0c;提示已经超出30天试用期限制…

单目深度估计之图像重构原理解析

一、参考资料 浅析自监督深度估计中的光度损失(Photometric Loss) 二、图像重构原理 设输入位姿估计网络的3帧连续单目序列为 < I t − 1 , I t , I t 1 > <I_{t-1},I_{t},I_{t1}> <It−1​,It​,It1​>&#xff0c;其中 t t t 为时间索引&#xff0c;…

Java SE 学习笔记(十九)—— XML、设计模式

目录 1 XML1.1 XML 概述1.2 XML 语法规则1.3 XML 文档约束&#xff08;了解&#xff09;1.3.1 DTD 约束1.3.2 schema 约束 2 XML 解析2.1 XML 解析概述2.2 Dom4J 解析 XML 文件2.3 XML 解析案例 3 XML 检索4 设计模式4.1 工厂模式4.2 装饰模式 1 XML 在有些业务场景下&#xff…

文心一言 VS 讯飞星火 VS chatgpt (123)-- 算法导论10.4 4题

四、用go语言&#xff0c;对于一个含 n个结点的任意有根树&#xff0c;写出一个 O(n)时间的过程&#xff0c;输出其所有关键字该树以左孩子右兄弟表示法存储。 文心一言&#xff1a; 在计算机科学中&#xff0c;左孩子右兄弟表示法是一种用于表示树状结构的方法&#xff0c;其…

springboot--基本特性--自定义 Banner

SpringApplication的使用 前言效果1.1 自定义banner1.2 自定义SpringApplication配置文件优先级高于程序化调整的优先级启动自定义banner关闭自定义banner 1.3 FluentBuilder API 前言 修改启动时候的修改banner 效果 1.1 自定义banner banner制定官网链接 在配置文件中设置…

sentinel规则持久化-规则同步nacos-最标准配置

官方参考文档&#xff1a; 动态规则扩展 alibaba/Sentinel Wiki GitHub 需要修改的代码如下&#xff1a; 为了便于后续版本集成nacos&#xff0c;简单讲一下集成思路 1.更改pom 修改sentinel-datasource-nacos的范围 将 <dependency><groupId>com.alibaba.c…

Qt之DLL的使用(关联DLL生成篇)

文章目录 一、示例二、使用步骤1.所需文件2.添加库3.选择库4.完成添加5.导入类使用 相关文章 一、示例 下图为使用DLL的示例图 二、使用步骤 1.所需文件 将所需要使用的相关库&#xff08;导出项目的库&#xff0c;包括Debug和Release两个编译模式的库&#xff0c;缺少某个…

【算法优选】前缀和专题——叁

文章目录 &#x1f60e;前言&#x1f334;[和为K的子数组](https://leetcode.cn/problems/subarray-sum-equals-k/description/)&#x1f6a9;题目描述&#x1f6a9;思路解析&#x1f6a9;代码实现 &#x1f384;[和可被 K 整除的子数组](https://leetcode.cn/problems/subarra…

【观察】Dell APEX云平台:引领多云时代上云新范式

毫无疑问&#xff0c;过去十多年是云计算发展的黄金十年&#xff0c;云计算理念不断被市场所接受&#xff0c;但随着企业上云深入和认知度的不断增加&#xff0c;摆在很多企业面前的选择题也发生了新变化&#xff0c;即从过去企业上云或不上云的纠结&#xff0c;转变成今天如何…

在pycharm中,远程操作服务器上的jupyter notebook

一、使用场景 现在我们有两台电脑&#xff0c;一台是拥有高算力的服务器&#xff0c;另一台是普通的轻薄笔记本电脑。如何在服务器上运行jupyter notebook&#xff0c;同时映射到笔记本电脑上的pycharm客户端中进行操作呢&#xff1f; 二、软件 pycharm专业版&#xff0c;jupy…

从一线到联合,克唑替尼在ALK阳性NSCLC治疗新旅程【医游记】

&#xff08;图片来源于网络&#xff09; 一、克唑替尼简介 克唑替尼(Crizotinib),商品名赛可瑞,是一款口服服用的小分子酪氨酸激酶抑制剂。克唑替尼最早于2011年被美国FDA批准用于ALK阳性晚期NSCLC的治疗。其主要靶点为间变淋巴瘤激酶(ALK)和ROS1(ROS proto-oncogene 1)融合…

Beyond Compare4 30天试用到期的2024最新解决办法

对于有文档对比需求的小伙伴们来说&#xff0c;Beyond Compare这款软件一定不陌生&#xff0c;这款软件是一款功能非常强大的文档对比软件。同时这款软件也是一款付费软件&#xff0c;需要用户付费才能够享有Beyond Compare的永久使用权&#xff0c;不过在付费之前&#xff0c;…

【OpenCV实现图像梯度,Canny边缘检测】

文章目录 概要图像梯度Canny边缘检测小结 概要 OpenCV中&#xff0c;可以使用各种函数实现图像梯度和Canny边缘检测&#xff0c;这些操作对于图像处理和分析非常重要。 图像梯度通常用于寻找图像中的边缘和轮廓。在OpenCV中&#xff0c;可以使用cv2.Sobel()函数计算图像的梯度…

部署私有仓库(笔记docker应用)

二&#xff1a;部署私有仓库 docker pull daocloud.io/library/registry:latest docker run --restartalways -d -p 5000:5000 daocloud.io/library/registry systemctl stop firewalld systemctl restart docker 宿主机ip端口 curl -I 127.0.0.1:5000 将镜像存放在仓…

[C++进阶篇]STL以及string的使用

目录 1. 什么是STL 2. STL库的六大组件 3. 标准库中的string类 3.3 对比size和capacity接口函数 size代表字符串有效长度 capacity代表字符串的实际长度 3.4 reserve&#xff0c;resize函数的使用 3.5 string类的访问和遍历 4. string的修改操作 5. insert和e…

3DMAX快速瓦片屋顶铺设插件使用方法详解

3DMAX快速瓦片屋顶铺设插件教程 3DMAX快速瓦片屋顶铺设插件&#xff0c;一键生成瓦片屋顶、瓦脊的插件&#xff0c;是一款非常实用的古风建筑建模插件。 【适用版本】 3dMax7或更新版本 【使用方法】 提示&#xff1a;建议使用本插件进行工作时&#xff0c;将3dMax单位设置为…

松下A6B伺服 马达不动问题解决

本人在用信捷XDH plc ethercat总线&#xff0c;连松下A6B伺服&#xff0c;轴配置完成轴调试时&#xff0c;出现能使能&#xff0c;但 马达不动的情况。 开始总怀疑时信捷PLC的原因&#xff0c;后面查明是输入口定义引起的。 用USB线连接伺服&#xff0c;打开PANAPARM软件,自…

[读论文] On Joint Learning for Solving Placement and Routing in Chip Design

0. Abstract 由于 GPU 在加速计算方面的优势和对人类专家的依赖较少&#xff0c;机器学习已成为解决布局和布线问题的新兴工具&#xff0c;这是现代芯片设计流程中的两个关键步骤。它仍处于早期阶段&#xff0c;存在一些基本问题&#xff1a;可扩展性、奖励设计和端到端学习范…

数据结构 | 顺序表专题

数据结构 | 顺序表专题 文章目录 数据结构 | 顺序表专题课前准备1. 目标2. 需要的储备知识3. 数据结构相关概念 开始顺序表1、顺序表的概念及结构2、顺序表分类3、动态顺序表的实现初始化顺序表打印顺序表内存容量的检查顺序表的尾插顺序表的尾删顺序表的头插顺序表的头删在顺序…