**题意:**Ming 打算旅游 n 天,其中 m 天在北京玩。他打算抽这 m 天中的第一天和另外一天去北大看看。为此他获得了这 n 天的北大的参观人数,他想选择人数相加和最少的两天去。又由于北京有交通管制,交通管制的当天哪也不能去,所以当 m 天中有几天交通管制,那么 Ming 就在北京多待几天。
思路:理清题意后这题并不难,不过刚开始实现的时候有点绕。告诉我们哪几天是交通管制,然后那几天就不能算在 m 天之内。我们事先将交通管制的那几天从 n 天里删去,提前利用另外的数组记录哪一个人数对应的是哪一天。这样处理后我们就只需要对这些剩下的人数从前往后扫一遍,找到对应的 m 天里的最少人数的两天即可。
拿题目中的第一个样例举个例子:
输入为:
7 3
6 9 10 1 0 8 35
3 5 6 2
读取操作后:
p数组:6,9,10,1,0,8,35
id数组:0,1,2,3,4,5,6
用bool数组记录哪天是交通管制,可见第 5、6、2 天交通管制。将这几天从 p 数组和 id 数组中删掉:
p 数组:6,9,1,0
id 数组:0,1,3,4
接下来从前往后遍历,当 m 天的第一天是第 0 天时,,,当 m 天的第一天是第 1 天时,,,
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
int N,M;
int p[210];
int id[210];
bool flag[210];
int main()
{
//freopen("in.txt", "r", stdin);
while(scanf("%d%d", &N, &M) == 2){
memset(flag, false, sizeof(flag));
for(int i=0; i<N; i++){
scanf("%d", &p[i]);
id[i] = i;
}
int q;
scanf("%d", &q);
for(int i=0; i<q; i++){
int tmp;
scanf("%d", &tmp);
flag[tmp] = true;
}
//下面这段就是把交通管制日从 p 数组和 id 数组中删掉
N -= q;
int pos = 0;
for(int i=0; i<N; i++,pos++){
if(!flag[pos]){
p[i] = p[pos];
id[i] = id[pos];
}
else{
i--;
}
}
int beg = 0;
int a, b;
int minn = INF;
while(beg+M-1 < N){
//printf("beg = %d\n", beg);
int pos;
for(int i=1; i<M; i++){
if(minn > p[beg+i]+p[beg]){
minn = p[beg+i]+p[beg];
a = beg;
b = beg+i;
}
}
beg++;
}
printf("%d %d\n", id[a], id[b]);
}
return 0;
}