奔跑吧,兄弟
提交数: 1029, 通过率: 39.26%, 平均分: 59.19
题目描述:
“奔跑吧,兄弟” 栏目组要在全国各地挑选节目录制的地点。有来自 K(1<=K<=100)个不同地区的 N(K<=N<=20,000)个选手送来了各自的竞选材料。由于参加的选手太多,没有办法同时呈现所有材料供评委进行选择。栏目组决定选择一段连续区间内的个人参选材料,这个区间内每个地区的参选选手至少要有 1名,求满足要求的最小区间长度。
输入格式:
第一行两个整数,n和k,表示有n个选手报名,k个不同的地区。
接下来n个数不大于k的整数,每两个数之间用一个空格隔开。
输出格式:
一个整数,表示最小长度的满足区间。
样例输入:
10 5 2 1 2 4 3 3 5 5 3 5
样例输出:
6
提示:
样例解释:
要覆盖5个地区的至少一名选手,那么最短长度的区间是从2个开始连续取6名选手, 1 2 4 3 3 5。
请完善下列程序(需要优化才能得满分):
//使用二分的思想计算最小区间
#include <bits/stdc++.h>
using namespace std;
int f[101], a[20101], k, n, ans;
//f[i]表示国籍为i的小朋友是否包含
bool pd( int m ) {
for (int i =1; i<= _______(1)_______; i++) { //枚举以i为起点的M个小朋友中,各个国籍是否包含
for (int j =1; j<=k; j++ ) //f数组元素重新初始化为0
f[ j ] = 0;
for ( int j=i; j<=i +m -1; j++ )
f [ a[j] ] = 1 ; //等于1,表示国籍为a(j)的小朋友已包含,0表示不包含
int t = 0 ; //t用于统计当前区间包含的国籍数量
for ( int j=1; j<=k; j++) //统计已包含的国籍的数量
_______(2)________ //填空2
if ( t == k)
return true; //若包含K个国籍,返回True
}
return false;
}
int main() {
cin >> n >> k;
for ( int i=1; i<=n; i++ ) cin >> a[i];
int i = k;
int j = n ; //答案的范围为K到N,即最少K,最多N个小朋友
while (i <= j) {
int m = (i + j) / 2 ; //二分,求中间值
if ( pd( m ) == true ) { //调用Pd函数,判断区间长度为M时,是否包含所有国籍
ans = m ; //若以M为区间长度可包含所有国籍,更新答案
j = m - 1 ;
} else
i = _____(3)_______; //填空3
}
cout << ans ;
return 0;
}
时间限制: 1000ms空间限制: 256MB
来源: 原创