【国科大算法设计与分析】第一次oj作业

目录

A-Nearest Point

Overview

​ After successive failures in the battles against the Union, the Empire retreated to its last stronghold. Depending on its powerful defense system, the Empire repelled the six waves of Union’s attack.

​ 在与联邦的战斗中接连失败后,帝国撤退到了它最后的据点。凭借其强大的防御系统,帝国击退了联邦的六波攻击。

​ After several sleepless nights of thinking, Arthur, General of the Union, noticed that the only weakness of the defense system was its energy supply.

​ 经过几个不眠之夜的思考,联邦将军注意到这个防御系统的唯一弱点是其能量供应。

​ The system was charged by N nuclear power stations and breaking down any of them would disable the system.

​ 该系统由 N 座核电站供电,破坏其中任何一座核电站都将使系统失效

The general soon started a raid to the stations by N special agents who were paradroped into the stronghold.

​ 将军很快派遣了 N 名特工对这些核电站发动突袭,这些特工被空投到据点中。

​ Unfortunately they failed to land at the expected positions due to the attack by the Empire Air Force. As an experienced general, Arthur soon realized that he needed to rearrange the plan.

​ 不幸的是,由于帝国空军的攻击,他们未能降落在预期位置。作为一名经验丰富的将军,亚瑟很快意识到他需要重新安排计划。

​ The first thing he wants to know now is that which agent is the nearest to any power station. Could you, the chief officer, help the general to calculate the minimum distance between an agent and a station?

​ 现在他最想知道的是哪个特工离任何一座核电站最近。作为首席军官,你能帮将军计算出特工与核电站之间的最小距离吗?

Input

The first line is a integer T representing the number of test cases.

第一行是一个整数 T,表示测试用例的数量。

Each test case begins with an integer N (1 ≤ N ≤ 1000).

每个测试用例以一个整数 N(1≤N≤1000)开始。

The next N lines describe the positions of the stations.

接下来的 N 行描述站点的位置。

Each line consists of two integers X (0 ≤ X ≤ 1000000000) and Y (0 ≤ Y ≤ 1000000000) indicating the positions of the station.

每行由两个整数 X(0≤X≤1000000000)和 Y(0≤Y≤1000000000)组成,表示站点的位置。

The next following N lines describe the positions of the agents. Each line consists of two integers X (0 ≤ X ≤ 1000000000) and Y (0 ≤ Y ≤ 1000000000) indicating the positions of the agent.

再接下来的 N 行描述代理的位置。每行由两个整数 X(0≤X≤1000000000)和 Y(0≤Y≤1000000000)组成,表示代理的位置。

Output

​ For each test case output the minimum distance with precision of three decimal placed in a separate line.

对于每个测试用例,在单独的一行中输出最小距离,精确到小数点后三位。

分治法

1)算法描述:

​ 已知集合S中有n个点,分治法的思想就是将S进行拆分,分为2部分求最近点对。算法每次选择一条垂线L,将S拆分左右两部分为SL和SR,L一般取点集S中所有点的中间点的x坐标来划分,这样可以保证SL和SR中的点数目各为n/2,(否则以其他方式划分S,有可能导致SL和SR中点数目一个为1,一个为n-1,不利于算法效率,要尽量保持树的平衡性)

依次找出这两部分中的最小点对距离:δL和δR,记SL和SR中最小点对距离δ = min(δL,δR),如图1:

image-20240922204729578

以L为中心,δ为半径划分一个长带,最小点对还有可能存在于SL和SR的交界处,如下图2左图中的虚线带,p点和q点分别位于SL和SR的虚线范围内,在这个范围内,p点和q点之间的距离才会小于δ,最小点对计算才有意义。

image-20240922204800229

​ 对于SL虚框范围内的p点,在SR虚框中与p点距离小于δ的顶多只有六个点,就是图二右图中的2个正方形的6的顶点

​ 这个可以反推证明,如果右边这2个正方形内有7个点与p点距离小于δ,例如q点,则q点与下面正方形的四个顶点距离小于δ,则和δ为SL和SR中的最小点对距离相矛盾。因此对于SL虚框中的p点,不需求出p点和右边虚线框内所有点距离,只需计算SR中与p点y坐标距离最近的6个点,就可以求出最近点对,节省了比较次数。(否则的话,最坏情形下,在SR虚框中有可能会有n/2个点,对于SL虚框中的p点,每次要比较n/2次,浪费了算法的效率)

代码描述

  1. 如果n=2,返回两点之间的距离,算法结束
  2. 如果n>2,以各点的x坐标的中位数m来划分两个子集SL,SR
  3. d1 = SL的最近对距离
  4. d2 = SR的最近对距离
  5. d = min{d1, d2}
  6. 找xm两边d的点,放入集合PL和PR中
  7. 将PL和PR按y坐标升序排列。
  8. 对PL和PR中的每个点p,在y坐标区间[y,y+d]内找到8个候选点,计算出最近距离d3
  9. 返回min{d, d3};

1)对点集S的点x坐标和y坐标进行升序排序,获得点集Sx和Sy

2)令δ=∞; //δ为最小点位距离

分析

归类为平面上最近点对问题:

算法导论中有对该问题的所有描述

用c++实现最近对问题、凸包问题

寻找最近点对

算法与程序设计(实验2)----分治法求最近点对问题

分治法学习笔记——最近点对问题

🤣 Github | 如何在Github上只下载一个文件或文件夹!?

求最近点对

《算法导论》实验五:最近点对算法(C++)

平面最近点距离问题(分治法) C++

[编程之美] PSet2.11 寻找最近点对

P1429 平面最近点对(加强版)

【计算机算法设计与分析】最近点对问题(C++_分治)

最邻近点对问题(Closest-Pair Problem):二维的分治解法详解

【算法设计与分析】分治法(最近点对问题)

算法分析与设计——最近点对问题

算法设计与分析实验一:分治法解决最近点对问题

C++ 中的sort()排序函数原理、用法看这一篇就够了

C++ sort()函数

C++中sort()函数的用法以及如何对类按某一成员参数排序

sort对类对象进行自定义排序/重载操作符/友元函数/仿函数

POJ 2659 Raid|分治法|平面最近点对

平面的分治与归并

B-A unique permutation

overview

​ A permutation of n + 1 n+ 1 n+1 is a bijective function of the initial n + 1 n + 1 n+1 natural numbers:0, 1, . . . n.
n + 1 n+1 n+1 的一个排列是前$ n+1 $个自然数 0、1、……n 的双射函数

[!NOTE]

n+1的排列,即前n+1个自然数0-n的双射函数

​ A permutation p p p is called antiarithmetic if there is no subsequence of it forming an arithmetic progression of length bigger than 2, i.e. there are no three indices 0 ≤ i < j < k < n 0 ≤ i < j < k < n 0i<j<k<n such that ( p i , p j , p k ) (p_i , p_j , p_k) (pi,pj,pk) forms an arithmetic progression.

​ 一个排列 p 被称为反算术排列,如果它不存在长度大于 2 的子序列构成等差数列,即不存在三个下标 0 ≤ i < j < k < n 0≤i<j<k<n 0ijkn 使得 ( p i , p j , p k ) (p_i , p_j , p_k) (pi,pj,pk)构成等差数列。

[!NOTE]

不存在长度大于2的子序列构成的等差数列,不存在三个下标构成的等差数列

​ For example, the sequence (2, 0, 1, 4, 3) is an antiarithmetic permutation of 5. The sequence (0, 5, 4, 3, 1, 2) is not an antiarithmetic permutation of 6 as its first, fifth and sixth term (0, 1, 2) form an arithmetic progression; and so do its second, fourth and fifth term (5, 3, 1).

​ 例如,序列(2,0,1,4,3)是 5 的一个反算术排列序列(0,5,4,3,1,2)不是 6 的反算术排列,因为它的第一项、第五项和第六项(0,1,2)构成等差数列;它的第二项、第四项和第五项(5,3,1)也构成等差数列。

[!NOTE]

5:0,1,2,3,4 (2,0,1,4,3)

得有一个检测是否为等差数列的算法

Your task is to generate an antiarithmetic permutation of n n n.

你的任务是生成一个$ n $的反算术排列。

Input

​ Each line of the input file contains a natural number 3 ≤ n ≤ 10000 3 ≤ n ≤ 10000 3n10000. The last line of input contains ‘0’ marking the end of input.

​ 输入文件的每一行都包含一个自然数 3 ≤ n ≤ 10000 3 ≤ n ≤ 10000 3n10000。输入的最后一行包含‘0’,标志着输入结束。

Output

​ For each $n $ from input, produce one line of output containing an (any will do) antiarithmetic permutation of $n $ in the format shown below.

​ 对于输入中的每个 n n n,输出一行,包含一个 $n $的反算术排列(任何一个都可以),格式如下所示。

Sample Input

3
5
6
0

Sample Output

3: 0 2 1
5: 2 0 1 4 3
6: 2 4 3 5 0 1

[!NOTE]

5: 2 0 1 4 3

5: 12340

2*2-3=1

暴力枚举

分析输入输出,输入是n,输出是一个反算术序列。

以n=3,3:012为例分析:

012021102120201210

[!NOTE]

XXX->3,2,1 = 3*2*1=6

等差数列:012,210是等差数列

以n=4,4:0123为例分析:

[!NOTE]

XXXX->4x3x2x1=24

012301320213023103120321
102310321203123013021320
201320312103213023012310
301230213102312032013210

[!NOTE]

对于n+1,共有n!个排序,其中的3或多个

for(int i = 1; i <=n; i++)

​ for(int j = 1; i+2)

012

210

a a+d a+2d

2a+2d-a=a+2d

分析

​ 有两种解决问题的思路,第一种是给定一个排序,能够判断它是不是反算数序列,然后给定n生成n!个排序,然后判断他是不是反算数序列。

如何判断某排序是否为反算数序列?

​ 先预处理保存每个数字的位置,然后枚举等差中项和的等差前项,计算出等差后项,判断位置符不符合即可。

预处理保存每个数字的位置:

void init(){
    int Num;
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &Num);  // 3:0 2 1
        num[Num] = i;     //num[0]=0,num[2]=1,num[1]=2;
        											//num和index反过来对应,先保存位置
        //num中为[0,2,1]
			}
}

枚举等差中项和的等差前项,计算出等差后项,判断位置符不符合

//continue:跳过本次循环题中剩下尚未执行的语句,立即进行下一次循环
//break:完全结束一个循环
bool judge()
{
    //3:0 2 1
    for(int i = 0; i < n; i++)
    {
        //j=3-1=2
        for(int j = n - 1; j >=0; j--)
        {
            //num[2]>num[0]
            if(num[j]>num[i])
                continue;
            int r = i*2-j;
            if(r < 0)
                continue;
            if(r >=n)
                break;
            if(num[r] > num[i])
                return false;
        }
    }
    return true;
}

参考资料

uva 11129 - An antiarithmetic permutation(递归)

11129 - An antiarithmetic permutation

UVA - 11129 An antiarithmetic permutation(分治)

10730-Antiarithmetic?【暴力枚举】

UVA 10730 - Antiarithmetic?(技巧枚举)

uva - 10730 - Antiarithmetic?(暴力枚举)

10730 - Antiarithmetic?(水题)

uva - 11129 - An antiarithmetic permutation(分治)

UVA - 11129 An antiarithmetic permutation(分治)

竞赛中应该用scanf还是cin? scanf&printf与cin&cout的比较+快读快写

scanf和cin的区别(别被方便蒙住了眼)

C-Lost items

overview

​ Rachid lives on a boat, and owns only a few items, n to be precise. He takes big care of his items, and measured the weight of each of them with high precision. Item i weights Wi micrograms. One night a thief visits his boat and steels some items. Rachid notices that the next morning, because the boat is lighter, and he could measure from the water level that this difference is D micrograms. He would like to know how many items are missing, just by examining these weights, and asks you for help.

​ Rachid lives on a boat, and owns only a few items, n n n to be precise. He takes big care of his items, and measured the weight of each of them with high precision.

​ Item i weights Wi micrograms. One night a thief visits his boat and steels some items. Rachid notices that the next morning, because the boat is lighter, and he could measure from the water level that this difference is D micrograms. He would like to know how many items are missing, just by examining these weights, and asks you for help.

​ 拉希德住在一艘船上,确切地说,他只有几样东西,数量为 n。他非常爱护自己的物品,并高精度地测量了每一件物品的重量。

​ 第 i 件物品重 Wi 微克。一天晚上,一个小偷光顾了他的船并偷走了一些物品。拉希德在第二天早上注意到船变轻了,他可以从水位测量出重量差为 D 微克。他想仅通过检查这些重量就知道丢失了多少件物品,并向你寻求帮助。

Input

The first line of the input consists of the number of test cases, T. T test cases follow. Each case consists of two lines, the first one containing two integers N and D, separated by a space. Then second line contains n integers, representing the weights of all items, separated by space.

The input satisfies the following limits.

1 ≤ T ≤ 20
1 ≤ N ≤ 30
0 ≤ D ≤ 3*10^10
0 ≤ W_i ≤ 10^9

​ 输入的第一行由测试用例的数量 T 组成。接下来有 T 个测试用例。每个测试用例由两行组成,第一行包含两个整数 N 和 D,用一个空格隔开。然后第二行包含 n 个整数,表示所有物品的重量,用空格隔开。

输入满足以下限制条件。

Output

​ For each test case output one line containing “Case #x: y”, where x is the case number (starting from 1). If the number of missing items could be determined, then y is this number. If there are several answers to the problem y is the string “AMBIGIOUS” and if there is no answer y is the string “IMPOSSIBLE” (quotes added for clarity and are not part of the output).

​ 对于每个测试用例,输出一行,包含 “Case #x: y”,其中 x 是用例编号(从 1 开始)。如果丢失物品的数量可以确定,那么 y 就是这个数量。如果这个问题有多个答案,y 是字符串 “AMBIGIOUS”;如果没有答案,y 是字符串 “IMPOSSIBLE”(为了清晰起见添加了引号,引号不是输出的一部分)。

参考资料

BURGLARY - Boat Burglary

BURGLARY - Boat Burglary洛谷中的题目

TOJ 4095 BoatBurglary 分治

TOJ 4095 BoatBurglary 分治

D-Extra Problem

Description

​ Cornered at last, Bessie has gone to ground in a remote farm. The farm consists of
N barns (2≤N≤7⋅10e4) and N−1 bidirectional tunnels between barns, so that there is a unique path between every pair of barns. Every barn which has only one tunnel is an exit. When morning comes, Bessie will surface at some barn and attempt to reach an exit.

​ But the moment Bessie surfaces at some barn, the law will be able to pinpoint her location. Some farmers will then start at various exit barns, and attempt to catch Bessie. The farmers move at the same speed as Bessie (so in each time step, each farmer can move from one barn to an adjacent barn). The farmers know where Bessie is at all times, and Bessie knows where the farmers are at all times. The farmers catch Bessie if at any instant a farmer is in the same barn as Bessie, or crossing the same tunnel as Bessie. Conversely, Bessie escapes if she reaches an exit barn strictly before any farmers catch her.

​ Bessie is unsure at which barn she should surface. For each of the N barns, help Bessie determine the minimum number of farmers who would be needed to catch Bessie if she surfaced there, assuming that the farmers distribute themselves optimally among the exit barns.

​ Note that the time limit for this problem is slightly larger than the default: 4 seconds for C/C++/Pascal, and 8 seconds for Java/Python.

​ 最终走投无路,贝茜躲进了一个偏远的农场。这个农场由 N 个谷仓(2≤N≤7×10e4)和 N - 1 条谷仓之间的双向隧道组成,因此每对谷仓之间都有一条唯一的路径。只有一条隧道的谷仓都是出口。当早晨来临时,贝茜将在某个谷仓出现并试图到达一个出口。
​ 但是,贝茜在某个谷仓出现的那一刻,执法人员将能够确定她的位置。然后一些农民将从各个出口谷仓开始,试图抓住贝茜。农民和贝茜的移动速度相同(所以在每个时间步,每个农民都可以从一个谷仓移动到相邻的谷仓)。农民始终知道贝茜在哪里,贝茜也始终知道农民在哪里。如果在任何时刻有一个农民与贝茜在同一个谷仓,或者正在穿过与贝茜相同的隧道,那么农民就抓住了贝茜。相反,如果贝茜在任何农民抓住她之前严格地到达一个出口谷仓,那么她就逃脱了。
​ 贝茜不确定她应该在哪个谷仓出现。对于 N 个谷仓中的每一个,假设农民在出口谷仓之间进行最优分布,帮助贝茜确定如果她在那里出现,需要的最少农民数量。
注意,这个问题的时间限制比默认的稍长:C/C++/Pascal 为 4 秒,Java/Python 为 8 秒。

Input

The first line of the input contains N. Each of the following N−1 lines specify two integers, each in the range 1…N, describing a tunnel between two barns.

​ 输入的第一行包含 N。接下来的 N - 1 行,每行指定两个整数,范围在 1…N 之间,描述两个谷仓之间的一条隧道。

Output

Please output N lines, where the ith line of output tells the minimum number of farmers necessary to catch Bessie if she surfaced at the ith barn.

​ 请输出 N 行,其中第 i 行输出告诉如果贝茜出现在第 i 个谷仓,抓住她所需的最少农民数量。

参考

usaco Cow at Large (双向bfs)

【LOJ #2386】「USACO 2018.01 Platinum」Cow at Large(点分治 / 树状数组)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后厂村路小狗蛋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值