题目相关
题目链接
AtCoder Beginner Contest 185 D 题,https://atcoder.jp/contests/abc185/tasks/abc185_d。
Problem Statement
There are N squares arranged in a row from left to right. Let Square i be the i-th square from the left.
M of those squares, Square A1, A2, A3, …, AM, are blue; the others are white. (M may be 0, in which case there is no blue square.)
You will choose a positive integer k just once and make a stamp with width k. In one use of a stamp with width k, you can choose k consecutive squares from the N squares and repaint them red, as long as those k squares do not contain a blue square.
At least how many uses of the stamp are needed to have no white square, with the optimal choice of k and the usage of the stamp?
Input
Input is given from Standard Input in the following format:
N M
A1 A2 A3 … AM
Output
Print the minimum number of uses of the stamp needed to have no white square.
Samples1
Sample Input 1
5 2
1 3
Sample Output 1
3
Explaination
If we choose k=1 and repaint the three white squares one at a time, three uses are enough, which is optimal.
Choosing k=2 or greater would make it impossible to repaint Square 2, because of the restriction that does not allow the k squares to contain a blue square.
Samples2
Sample Input 2
13 3
13 3 9
Sample Output 2
6
Explaination
One optimal strategy is choosing k=2 and using the stamp as follows:
- Repaint Squares 1,2 red.
- Repaint Squares 4,5 red.
- Repaint Squares 5,6 red.
- Repaint Squares 7,8 red.
- Repaint Squares 10,11 red.
- Repaint Squares 11,12 red.
Note that, although the k consecutive squares chosen when using the stamp cannot contain blue squares, they can contain already red squares.
Samples3
Sample Input 3
5 5
5 2 1 4 3
Sample Output 3
0
Explaination
If there is no white square from the beginning, we do not have to use the stamp at all.
Samples4
Sample Input 4
1 0
Sample Output 4
1
Explaination
M may be 0.
Constraints
- 1≤N≤10^9
- 0≤M≤2×10^5
- 1≤Ai≤N
- Ai are pairwise distinct.
- All values in input are integers.
题解报告
题目翻译
我们有 N 个正方形,从左到右排列。其中 M 个正方形已经被涂为红色,记为 A1, A2, ..., AM。剩下的都是白色。M 可以为零。
我们要选择一个正整数 k,我们可以将连续 k 个白色正方形涂成红色,注意已经涂成红色的可以重复上色。只允许对白色正方形涂成红色。请找出做少的涂色次数。
题目分析
又是一个模拟题。这次的 D 题有点水。我们先分析一下数据,然后再说伪码。
样例数据分析
样例数据 1
根据样例数据,我们可以绘制出如下图片。
如上图所示,一共 5 个正方形,编号为 1 ~ 5,其中 1 和 3 被涂成蓝色,我们需要将剩下的白色正方形涂成红色。上图有两块连续白色区域,第一个区域长度为 1,第二个区域长度为 2。由于不能将蓝色正方形涂成红色,我们只能选择最小的长度 k=1。这样涂色的过程如下:
第一次。将 2 号正方形涂成红色。
第二次。将 4 号正方形涂成红色。
第三次。将 5 号正方形涂成红色。
样例数据 2
根据样例数据,我们可以绘制出如下图片。
如上图所示,一共 13 个正方形,编号为 1 ~ 13,其中 3、9 和 13 被涂成蓝色,我们需要将剩下的白色正方形涂成红色。上图有三块连续白色区域,第一个区域长度为 2,第二个区域长度为 5,第二个区域长度为 3。由于不能将蓝色正方形涂成红色,我们只能选择最小的长度 k=2。这样涂色的过程如下:
第一次。将 1、2 号正方形涂成红色。
第二次。将 4、5 号正方形涂成红色。
第三次。将 6、7 号正方形涂成红色。
第四次。将 7、8 号正方形涂成红色。注意这里按照规则,将 7 号重复涂色。
第五次。将 10、11 号正方形涂成红色。
第六次。将 11、12 号正方形涂成红色。注意这里按照规则,将 11 号重复涂色。
样例数据 3
根据样例数据,我们可以绘制出如下图片。
如上图所示,一共 5 个正方形,编号为 1 ~ 5,所有正方形都被涂成蓝色。因此答案为 0。
样例数据 4
根据样例数据,我们可以绘制出如下图片。
如上图所示,一共 1 个正方形,编号为 1。其中没有正方形涂成蓝色,我们需要将剩下的白色正方形涂成红色。上图有一块连续白色区域,第一个区域长度为 1。我们只能选择最小的长度 k=1。这样涂色的过程如下:
第一次。将 1 号正方形涂成红色。
算法设计
从上面的样例数据分析,我们可以看出重点是要找到这个最小的 K。
细节
1、由于样例数据没有保证排序,参考样例 2 和样例 3,我们需要将输入的 A 进行排序。
2、通过遍历排序后的 A,我们可以得到 gap 数组,表示每个连续白色快长度。
3、找出 K。通过遍历 gap 数组,找出 gap 数组的非零最小值即可。
4、计算涂色的次数。我们可以遍历 gap 数组,计算 gap[i] 和 k 的关系。
伪码
读取n,m
读取数组 A
排序数组 A
遍历数据 A,计算间隔数组 gap
遍历数据 gap,找到最小非零 k
遍历数据 gap,计算 ans
AC 参考代码
//https://atcoder.jp/contests/abc185/tasks/abc185_d
//D - Stamp
#include <bits/stdc++.h>
using namespace std;
//如果提交到OJ,不要定义 __LOCAL
//#define __LOCAL
const int MAXN=1e9+4;
const int MAXM=2e5+4;
int a[MAXM];
int gap[MAXM];
int main() {
#ifndef __LOCAL
//这部分代码需要提交到OJ,本地调试不使用
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#endif
int n, m;
cin>>n>>m;
for (int i=1; i<=m; i++) {
cin>>a[i];
}
a[m+1]=n+1;
sort(a+1, a+m+1);
//差分
int k=MAXN;
int ans=0;
for (int i=1; i<=m+1; i++) {
gap[i]=a[i]-a[i-1]-1;
if (gap[i]<k && gap[i]>0) {
k=gap[i];
}
}
if (MAXN!=k) {
for (int i=1; i<=m+1; i++) {
ans += ceil(1.0*gap[i]/k);
}
}
cout<<ans<<"\n";
#ifdef __LOCAL
//这部分代码不需要提交到OJ,本地调试使用
system("pause");
#endif
return 0;
}
效率不是很高。再准备期末考试的间隙,防止老年痴呆,先将就一下。
时间复杂度
O(MlogM)。注意我们有一个排序,这个时间复杂度最高。
空间复杂度
O(M)。