【OJ for Divide and Conquer】OJ题解

文章目录

  • 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.

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FL Studio21.2汉化免费版下载

FL studio又被国内网友称之为水果音乐制作软件21版本&#xff0c;是Image-Line公司成立23周年而发布的一个版本&#xff0c;FL studio中文版是目前互联网上最优秀的完整的软件音乐制作环境或数字音频工作站&#xff0c;FL Studio包含了编排&#xff0c;录制&#xff0c;编辑&am…

【影刀演示_发送邮件的格式化HTML留存】

发送邮件的格式化HTML留存 纯文本&#xff1a; 亲爱的小张: 端午节将至&#xff0c;公司为了感谢大家一年以来的辛勤工作和付出&#xff0c;特别为大家准备了京客隆超市福利卡&#xff0c;希望为大家带来些许便利和节日的喜悦。 以下是您的福利卡卡号和密码&#xff0c;请您…

VBA宏查找替换目录下所有Word文档中指定字符串

原来搞质量管理&#xff0c;要替换质量文件里面所有特定名称或者某一错误时&#xff0c;需要逐一打开所有文件&#xff0c;非常麻烦&#xff0c;所以写了个VBA程序。过了这么多年&#xff0c;突然又要做同样的事情&#xff0c;发现新版本Word不支持其中的Application.FileSearc…

PHP | php入门知识(if、switch、数组、数组排序、超级全局变量)

文章目录 一、php条件语句&#xff08;if、switch&#xff09;1. if语句2. if...else语句3. if...elseif...else语句4. switch语句 二、数组1&#xff09;数值数组1. 创建数值数组的两种方法&#xff1a;2. 获取数组的长度&#xff08;count()函数&#xff09;3. 遍历数值数组&…

基于AI与物联网技术的智能视频监控系统架构剖析

智能视频监控系统正逐渐成为我们日常生活和工作中不可或缺的一部分。基于物联网的智能监控系统架构为我们在各个领域提供了更高效、智能化和安全的监控解决方案。本文将以旭帆科技EasyCVR视频监控云平台为例&#xff0c;介绍基于AI、物联网的智能监控系统的架构&#xff0c;并探…

san.js源码解读之模版解析(parseTemplate)篇——readAccessor函数

相关文章&#xff1a;san.js源码解读之模版解析(parseTemplate)篇——readIdent函数 一、源码分析 /*** 读取访问表达式** param {Walker} walker 源码读取对象* return {Object}*/ function readAccessor(walker) {var firstSeg readIdent(walker);switch (firstSeg) { // …

SpringCloud 微服务全栈体系(九)

第九章 Docker 三、Dockerfile 自定义镜像 常见的镜像在 DockerHub 就能找到&#xff0c;但是我们自己写的项目就必须自己构建镜像了。 而要自定义镜像&#xff0c;就必须先了解镜像的结构才行。 1. 镜像结构 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而…

百货中心供应链管理系统

毕业设计说明书 百货中心供应链管理系统 百货中心供应链管理系统 摘要 近年来&#xff0c;随着计算机技术的发展&#xff0c;以及信息化时代下企业对效率的需求&#xff0c;计算机技术与通信技术已经被越来越多地应用到各行各业中去。百货中心作为物流产业链中重要的一环&a…

基于Qt 文本读写(QFile/QTextStream/QDataStream)实现

​ 在很多时候我们需要读写文本文件进行读写,比如写个 Mp3 音乐播放器需要读 Mp3 歌词里的文本,比如修改了一个 txt 文件后保存,就需要对这个文件进行读写操作。本章介绍简单的文本文件读写,内容精简,让大家了解文本读写的基本操作。 ## QFile 读写文本 QFile 类提供了读…

基于机器视觉的二维码识别检测 - opencv 二维码 识别检测 机器视觉 计算机竞赛

文章目录 0 简介1 二维码检测2 算法实现流程3 特征提取4 特征分类5 后处理6 代码实现5 最后 0 简介 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的二维码识别检测 - opencv 二维码 识别检测 机器视觉 该项目较为新颖&#xff0c;适合作为竞赛课…

07. 蜂鸣器

07. 蜂鸣器 硬件原理分析代码编写 硬件原理分析 此处为PNP型三极管&#xff0c;BEEP为低的时候三极管才会导通&#xff0c;也就是BEEP0时&#xff0c;蜂鸣器会叫。BEEP是通过SNVS_TAMPER1这个IO控制的 代码编写 将前面的bsp、imx6ul、obj和project拷贝过来 初始化SNVS_TAMPE…

MSQL系列(十) Mysql实战-Join驱动表和被驱动表区分

Mysql实战-Join驱动表和被驱动表区分 前面我们讲解了Mysql的查询连接Join的算法原理, 我发现大家都知道小表驱动大表,要让小表作为驱动表, 现在有2个问题 查询多表, 到底哪个是驱动表?哪个是被驱动表, 如何区分?索引如何优化,到底是加在驱动表上,还是被驱动表上? 今天我们…

40基于MATLAB,使用模板匹配法实现车牌的识别。

基于MATLAB&#xff0c;使用模板匹配法实现车牌的识别。具体包括将原图灰度化&#xff0c;边缘检测&#xff0c;腐蚀操作&#xff0c;车牌区域定位&#xff0c;车牌区域矫正&#xff0c;二值化&#xff0c;均值滤波&#xff0c;切割&#xff0c;字符匹配&#xff0c;最终显示车…

codeforces (C++ Doremy‘s Paint 3)

题目&#xff1a; 翻译&#xff1a; 思路&#xff1a; 1、题目意思&#xff1a;将数组中的数进行排列&#xff0c;任意相邻两个数的和都相等&#xff0c;才能说这个数组为好。一下分三种情况讨论。 2、当数组中有三种及三种以上的数字&#xff0c;那任意相邻两个数的和都相等必…

智慧停车视频解决方案:如何让AI助力停车管理升级?

一、项目背景 停车场的管理区域由于面积比较大&#xff0c;进出车辆多&#xff0c;所以在保安方面决不能有任何的麻痹和松懈&#xff0c;继续采用过去保安方式已远远不能满足现代安全防范的需求。为满足停车场的安全和科学系统化管理的需要&#xff0c;以及为了对随时发生的情…

精品Python的定制化图书借阅推荐引擎设计与实现

《[含文档PPT源码等]精品基于Python的定制化图书推荐引擎设计与实现》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技…

【持续交付】个人网站

今天给大家演示下如何基于Vuepress尝试持续交付博客网站。 也尝试过其他的方案&#xff0c;比如使用Typora导出html文件&#xff0c;并scp该文件到服务器上。 效果图 该持续交付主流程如下图 提交代码后会触发webHook生成version.txt,部署脚本每分钟轮询一次检测是否存在vers…

物联网和互联网医院小程序:如何实现医疗设备的远程监测和管理?

物联网&#xff08;IoT&#xff09;技术的发展为医疗设备的远程监测和管理提供了巨大的机会。结合互联网医院小程序&#xff0c;我们可以实现对医疗设备的远程访问、监控和管理&#xff0c;从而提高医疗服务的质量和效率。本文将介绍如何实现医疗设备的远程监测和管理&#xff…

漏洞复现-dedecms文件上传(CVE-2019-8933)

dedecms文件上传_CVE-2019-8933 漏洞信息 Desdev DedeCMS 5.7SP2版本中存在安全漏洞CVE-2019-8933文件上传漏洞 描述 ​ Desdev DedeCMS&#xff08;织梦内容管理系统&#xff09;是中国卓卓网络&#xff08;Desdev&#xff09;公司的一套基于PHP的开源内容管理系统&#x…

磁盘调度算法之先来先服务(FCFS),最短寻找时间优先(SSTF),扫描算法(SCAN,电梯算法),LOOK调度算法

目录 1.一次磁盘读/写操作需要的时间1.寻找时间2.延迟时间3.传输时间4.影响读写操作的因素 2.磁盘调度算法1.先来先服务(FCFS)1.例题2.优缺点 2.最短寻找时间优先(SSTF)1.例题2.优缺点3.饥饿的原因 3.扫描算法(SCAN)1.例题2.优缺点 4.LOOK调度算法1.例题2.优点 5.循环扫描算法(…